Reputation: 255
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!
Upvotes: 1
Views: 5172
Reputation: 23442
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.
Upvotes: 10
Reputation: 48871
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
Upvotes: 1
Reputation: 30168
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];
....
}
Upvotes: 0