I have an AsyncTask (in a separate file) which is invoked on an activity. When I instantiate the AsyncTask, I send the activity as a param. How can I access the acitivity's instance variables from the onPostExecute method of the AsyncTask?
Thanks!
I have an AsyncTask (in a separate file) which is invoked on an activity. When I instantiate the AsyncTask, I send the activity as a param. How can I access the acitivity's instance variables from the onPostExecute method of the AsyncTask?
Thanks!
You must be careful when passing an Activity or Context
to an AsyncTask
that is not an inner (non-static) class of an Activity - this is because in this case the lifetime of the Activity
/Context
and the AsyncTask
are different, and if you hold on to an Activity
/Context
for longer than you should you will cause memory leaks.
Rather than holding onto the Activity or activity context itself in your AsyncTask
you should keep a WeakReference
to the Activity. This will ensure that the memory associated with the Activity can be reclaimed by the garbage collector (GC) when needed.
public class MyTask extends AsyncTask<..., ..., ...> {
private WeakReference<MyActivity> mParentActivity = null;
public MyTask(MyActivity parentActivity) {
mParentActivity = new WeakReference<MyActivity>(parentActivity);
}
@Override
public ... doInBackground(... params) {
// do some stuff
// now we do something that requires the context
if (mParentActivity.get() != null) {
// the WeakReference is still valid and hasn't been reclaimed
// by the GC
final MyActivity parentActivity = mParentActivity.get();
parentActivity.doSomething();
}
// return result
}
}
When passing a Context
always try to use the ApplicationContext
where possible as this is the longest-lived context.
Similar to Programmer Bruce's answer but instead of passing the Activity as a Param through the AsyncTask itself, simply add a constructor to take the parent Activity. Example from my own code...
public class FileDownloader extends AsyncTask<..., ..., ...> {
private MyActivity parentActivity = null;
public FileDownloader(MyActivity parentActivity) {
this.parentActivity = parentActivity;
}
}
When you create it in your Activity just do this...
FileDownloader fdl = new FileDownloader(this);
fdl.execute(...);
EDIT: In reply to your comment, make sure mLogin is declared as public
then use...
parentActivity.mLogin
If that doesn't work, try...
((MyActivity)parentActivity).mLogin
You can extend from AsyncTask<Object, x x>
, and you can then pass in any number of arbitrary parameters you like, no need to pass around reference to the whole Activity.
new CustomTask().execute(param1, param2, param3);
Which you can reference in your doInBackground:
public Void doInBackground(Object... params) {
Integer id = (Integer) params[0];
String name = (String) params[1];
....
}