Access instance variables from an activity inside a AsyncTask

南楼画角 提交于 2019-12-24 11:25:15

问题


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!


回答1:


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.




回答2:


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



回答3:


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];
    ....
 } 


来源:https://stackoverflow.com/questions/6024658/access-instance-variables-from-an-activity-inside-a-asynctask

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!