问题
I am trying to set my toolbar title from an async task. I am getting a cannot resolve method getActivity() in this line:
((ActionBarActivity)getActivity()).getSupportActionBar().setTitle(name);
My code looks like this:
/**
* Created by Mike on 2/28/15.
*/
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.preference.PreferenceManager;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RatingBar;
import android.widget.TextView;
import android.widget.Toast;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* Created by Mike on 4/26/14.
*/
public class GetBeerDataJSON2 extends AsyncTask<String, Void, String> {
Context c;
String id;
private ProgressDialog Dialog;
public GetBeerDataJSON2 (Context context, String beerID)
{
c = context;
id = beerID;
Dialog = new ProgressDialog(c);
}
@Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
return readJSONFeed(arg0[0]);
}
protected void onPreExecute() {
Dialog.setMessage("Getting beer information");
Dialog.setTitle("Loading");
Dialog.show();
}
protected void onPostExecute(String result){
//decode json here
try{
JSONObject o = new JSONObject(result);
//get beer details
//todo: lets get things from our new JSON
String name = o.getString("name");
String beerDescription = o.getString("description");
String abv = o.getString("abv");
String ibu = o.getString("ibu");
String image = o.getString("icon");
String glass = o.getString("glass");
String beerBreweryStyle = o.getString("style");
String beerBreweryName = o.getString("brewery");
String status = o.getString("status");
String rating = o.getString("rating");
String food = o.getString("food");
int beerRate = 0;
beerRate = o.getInt("userRating");
//prepare buttons
//Button buttonBrewery = (Button) ((Activity) c).findViewById(R.id.buttonBrewery);
//Button buttonStyle = (Button) ((Activity) c).findViewById(R.id.buttonStyle);
TextView tv_breweryName = (TextView) ((Activity) c).findViewById(R.id.beerBreweryName);
TextView tv_styleName = (TextView) ((Activity) c).findViewById(R.id.beerStyleName);
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(c);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("styleName",beerBreweryStyle);
editor.putString("beerName",name);
editor.putString("lastBeer",name);
editor.putString("breweryName",beerBreweryName);
editor.putString("styleName",beerBreweryStyle);
editor.commit();
((ActionBarActivity)getActivity()).getSupportActionBar().setTitle(name);
//create text views
TextView styleTitle = (TextView) ((Activity) c).findViewById(R.id.beerTitle);
styleTitle.setText(name);
TextView textABV = (TextView) ((Activity) c).findViewById(R.id.abv);
textABV.setText(abv);
TextView textIBU = (TextView) ((Activity) c).findViewById(R.id.IBU);
textIBU.setText(ibu);
TextView textGlass = (TextView) ((Activity) c).findViewById(R.id.glass);
textGlass.setText(glass);
TextView textDescription= (TextView) ((Activity) c).findViewById(R.id.beerDescription);
textDescription.setText(beerDescription);
String breweryButton = "Brewery: ";
String styleButton = "Style: ";
//todo: add beer name to shared prefs
tv_breweryName.setText(beerBreweryName);
tv_styleName.setText(beerBreweryStyle);
//get user id
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
String userName = prefs.getString("userName", null);
final String userID = prefs.getString("userID", null);
//check if user has beer
String url = "http://www.beerportfolio.com/app_checkBeer.php?";
String userURLComp = "u=" + userID;
final String beerID = "&b=" + id;
url = url + userURLComp + beerID;
//new CheckBeerJSON(c,id,userID).execute(url);
//todo: add code for check beer here
if(status.equals("no")){
//clear loader image
LinearLayout ll = (LinearLayout) (LinearLayout)((Activity) c).findViewById(R.id.addBeerLayout);
ll.removeAllViews();
//Add beer add button
LayoutInflater mInflater = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout addButton = (LinearLayout)((Activity) c).findViewById(R.id.addBeerLayout);
addButton.addView(mInflater.inflate(R.layout.addbeerbutton_layout, null));
//add on click listener here
Button bt4 = (Button)((Activity) c).findViewById(R.id.button1);
bt4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// do whatever stuff you wanna do here
//get beer details
String url2 = "http://www.beerportfolio.com/app_addBeer.php?";
String urlUserID = "u=" + userID;
String urlBeerID = "&bID=" + id;
Log.d("url", id);
//construct url for adding beer
url2 = url2 + urlUserID + urlBeerID;
Log.d("url", url2);
//execute async on url to add to brewery
new AddBeer(c).execute(url2);
//to do: change to start rater
LinearLayout ll = (LinearLayout) ((Activity) c).findViewById(R.id.addBeerLayout);
ll.removeAllViews();
//add rater
LayoutInflater inflater = (LayoutInflater)((Activity) c).getSystemService(((Activity) c).LAYOUT_INFLATER_SERVICE);
LinearLayout addButton = (LinearLayout)((Activity) c).findViewById(R.id.addBeerLayout);
addButton.addView(inflater.inflate(R.layout.addrate_layout, null));
//add listener to rate button todo
//add listener to bar
addListenerOnRatingBar(c);
}
});
}
else{
//clear loader image
LinearLayout ll = (LinearLayout) (LinearLayout)((Activity) c).findViewById(R.id.addBeerLayout);
ll.removeAllViews();
//inflate star rater
LayoutInflater mInflater = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout addButton = (LinearLayout)((Activity) c).findViewById(R.id.addBeerLayout);
addButton.addView(mInflater.inflate(R.layout.addrate_layout, null));
RatingBar r = (RatingBar) ((Activity) c).findViewById(R.id.beerRatingBar);
//get user data
//get beer rating with async task and update rate bar
String url2 = "http://www.beerportfolio.com/app_getRating.php?";
String userURLComp2 = "u=" + userID;
String beerID2 = "&b=" + beerID;
url = url + userURLComp2 + beerID2;
//new GetUserRating(c,r).execute(url2);
r.setRating(beerRate);
//add listener to bar
addListenerOnRatingBar(c);
}
//end code here
//todo: get rate code goes here
TextView tv1 = (TextView) ((Activity) c).findViewById(R.id.beerRating);
tv1.setText(rating + " / 5");
//end rate code
String url2 = "http://beerportfolio.com/app_beerDetails2.php?u="+ userID + "&b=" + beerID;
//new GetBeerRateJSON(c,id).execute(url2);
ImageView im1 = (ImageView) ((Activity) c).findViewById(R.id.image);
if(image.equals("N/A")){
//set image as png
im1.setImageResource( R.drawable.noimage);
}
else{
ImageDownloadTask imageD = new ImageDownloadTask(im1);
imageD.execute(image);
}
//tdo: add food paring
if (food.equals("N/A")){
}
Dialog.dismiss();
}
catch(Exception e){
}
}
private void addListenerOnRatingBar(Context view) {
RatingBar ratingBar = (RatingBar) ((Activity) view).findViewById(R.id.beerRatingBar);
ratingBar.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
public void onRatingChanged(RatingBar ratingBar, float rating,
boolean fromUser) {
//next async task to update online database
float stars = ratingBar.getRating();
//get user details
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
String userID = prefs.getString("userID", null);
//get beer id
String beerID = id;
//get rating
String urlRate = "r=" + String.valueOf(ratingBar.getRating());
String urlUserID = "&u=" + userID;
String urlBeerID = "&b=" + beerID;
//construct url
String url2 = "http://www.beerportfolio.com/app_rateUpdate.php?";
url2 = url2 + urlRate + urlUserID + urlBeerID;
//async task to update rating in database
new UpdateRating(c).execute(url2);
}
});
}
public String getName(JSONObject json){
String holder;
try{
holder = json.getJSONObject("data").getString("name");
} catch (JSONException e) {
holder = "N/A";
}
return holder;
}
public String getABV(JSONObject json){
String holder;
try{
holder = json.getJSONObject("data").getString("abv");
} catch (JSONException e) {
holder = "N/A";
}
return holder;
}
public String getIBU(JSONObject json){
String holder;
try{
holder = json.getJSONObject("data").getString("ibu");
} catch (JSONException e) {
holder = "N/A";
}
return holder;
}
public String getImage(JSONObject json){
String holder;
try{
holder = json.getJSONObject("data").getJSONObject("labels").getString("large");
} catch (JSONException e) {
holder = "N/A";
}
return holder;
}
public String getGlass(JSONObject json){
String holder;
try{
holder = json.getJSONObject("data").getJSONObject("glass").getString("name");
} catch (JSONException e) {
holder = "N/A";
}
return holder;
}
public String getBreweryName(JSONObject json){
String holder;
try{
holder = json.getJSONObject("data").getJSONArray("breweries").getJSONObject(0).getString("name");
} catch (JSONException e) {
holder = "N/A";
}
return holder;
}
public String getBreweryStyle(JSONObject json){
String holder;
try{
holder = json.getJSONObject("data").getJSONObject("style").getString("name");
} catch (JSONException e) {
holder = "N/A";
}
return holder;
}
public String getDescription(JSONObject json){
String holder;
try{
holder = json.getJSONObject("data").getString("description");
} catch (JSONException e) {
holder = "N/A";
}
return holder;
}
public String readJSONFeed(String URL) {
StringBuilder stringBuilder = new StringBuilder();
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(URL);
try {
HttpResponse response = httpClient.execute(httpGet);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) {
HttpEntity entity = response.getEntity();
InputStream inputStream = entity.getContent();
BufferedReader reader = new BufferedReader(
new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
inputStream.close();
} else {
Log.d("JSON", "Failed to download file");
}
} catch (Exception e) {
Log.d("readJSONFeed", e.getLocalizedMessage());
}
return stringBuilder.toString();
}
}
I feel like I need to use the context c that I bring in, but every combination I have tried has failed me.
回答1:
Use context:
((ActionBarActivity)context).getSupportActionBar().setTitle(name);
回答2:
At first you should do all time consuming operation in a doInBackground
method. This also include parsing JSON data. In onPreExecute
and onPostExecute
method you should do only GUI things.
Don't use activity or activity context directly in AsyncTask
class. Use listeners together with WeakReference
to change GUI things. For example:
public class MyAsyncTask extends AsyncTask<String, Void, String> {
public interface TaskListener {
void onTitleReceived(String title);
}
private final WeakReference<TaskListener> mTaskListenerRef;
public MyAsyncTask(TaskListener listener) {
this.mTaskListenerRef = new WeakReference<>(listener);
}
public void notifyTitleReceived(String title) {
TaskListener listener = mTaskListenerRef.get();
if (listener != null) {
listener.onTitleReceived(title);
}
}
protected void onPostExecute(String result){
...
notifyTitleReceived(newTitle);
...
}
}
public class MyActivity extends ActionBarActivity implements MyAsyncTask.TaskListener {
@Override
public void onTitleReceived(String title) {
getSupportActionBar().setTitle(title);
}
private void runTask() {
new MyTask(this).execute();
}
}
回答3:
define an static instance of actvity , set it before excute()
in your GetBeerDataJSON2 class
public static ActionBarActivity instance = null;
in your ActionBarActivity class :
onCreate(Bundle bundle){
GetBeerDataJSON2 task = new GetBeerDataJSON2() ;
task.instance = this;
task.excute();
}
another solotion is passing this
as the context
in your constructor of GetBeerDataJSON2
and cast it to ActionBarActivity
anyway better way of doing this is using libraries like volley to get json rather than building the wheel
回答4:
Combining answers in constructor while creating instance of GetBeerDataJSON2(Context, Stirng) in Activity code pass 'this' as first argument.
And cast it as :
((ActionBarActivity) context).getSupportActionBar().setTitle(name);
Instead of :
((ActionBarActivity)getActivity()).getSupportActionBar().setTitle(name);
Error Because there is no method getActivity() defined for AsynchTask.
来源:https://stackoverflow.com/questions/28955810/asynctask-getactivity