Can't access "findViewById" in AsyncTask
Pass your inflated view to the AsyncTask like this :
public class RecuperarComentarisFoto extends AsyncTask<String, String, String>{
private Context mContext;
private View rootView;
[...]
public RecuperarComentarisFoto(Context context, View rootView){
this.mContext=context;
this.rootView=rootView;
}
@Override
protected void onPreExecute() {
[...]
}
@Override
protected String doInBackground(String... arg0) {
params.add(new BasicNameValuePair("pid", "1"));
JSONObject json = jsonParser.makeHttpRequest(url_get_comentaris, "GET", params);
JSONArray productObj;
//HERE I RETRIEVE DATA FROM JSON. ITS WORKING OK.
return null;
}
@Override
protected void onPostExecute(String result) {
//super.onPostExecute(result); <--GET RID OF THIS (it will screw up on 2.1 devices)
this.pDialog.dismiss();
// use rootview to findViewById
TextView comentariEditText = (TextView) rootView.findViewById(R.id.commentsMostrar);
}
Then call like so,
View myFragmentView = inflater.inflate(R.layout.fragment_a, container, false);
cont=getActivity();
new RecuperarComentarisFoto(cont, myFragmentView).execute();
Make your AsyncTask independent of Activity
What if
- Your
AsyncTask
is a seperate Java class (Outside of Activity) and you still want to access the View elements of anyActivity
fromAsyncTask
. - You want to reuse your
AsyncTask
with some other Activity without any code change in the yourAsyncTask
Answer is. Use an interface
Advantage?
An interface makes things independent (loosely coupled)
You can follow these steps:
1) Create an interface
public interface AsyncTaskListener{
public void giveProgress(int progress);
}
2) Use listener in your AsyncTask
DownloadSongTask extends AsyncTask<String,Integer,Void>{
private AsyncTaskListener listener;
public DownloadSongTask(Context context)
{
listener= (AsyncTaskListener)context; // Typecast
}
@Override
public void doInbackGround(String... params)
{
// Download code
int downloadPerc = // calculate that
publish(downloadPerc);
}
@Override
public void onProgressUpdate(Integer... params)
{
listener.giveProgress(params[0]); // Use it
}
}
3) Implement the interface in the Activity and Override method
public class YourActivity extends AppcompatActivity implements AsyncTaskListener{
private TextView textView;
// Activity code //
new DownloadSongTask(this).execute("Paradise.mp3"); // this is how you start Task
@Override
public void giveProgress(int progress){
textView.setText(progress+"");
}
}
Future
You will not realize the beauty of your code until you have to use Your AsyncTask in some other Activity.
Lets say in future you want to use this AsyncTask
in some Other Activity which shows progress in a Spinner.
How will you use it ?
Simple! implement the interface and override the method.
public class YourActivity extends AppcompatActivity implements AsyncTaskListener{
private Spinner spinner;
// Activity code //
new DownloadSongTask(this).execute("Paradise.mp3"); // this is how you start Task
@Override
public void giveProgress(int progress){
// Your Spinner code
}
}
try as after passing MyFragmentA
context instead of getActivity()
:
cont=this;
new RecuperarComentarisFoto(cont).execute();
and change RecuperarComentarisFoto
as
public class RecuperarComentarisFoto extends AsyncTask<String, String, String>{
public Fragment mContext;
[...]
public RecuperarComentarisFoto(Fragment context){
this.mContext=context;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
this.pDialog.dismiss();
TextView comentariEditText =
(TextView)mContext.findViewById(R.id.commentsMostrar);
}
//...your code..