AsyncTask的onPostExecute()中有什么上下文?

时间:2012-05-18 09:50:38

标签: android android-asynctask

我确实在Activities中使用了很多AsyncTasks作为私有内部类。从一开始就让我感到困惑的一件事是我在onPostExecute()中得到了什么上下文?

如果查看下面显示的精简示例,可以在onPostExecute()中使用getString()。该呼叫使用了什么上下文?在doInBackground(例如OrientationChange)期间,Activity可能已经更改,因此它不能是该上下文。

目前我修补了Activity上下文(task.context = this)并使用了特定的上下文(context.getString())。

我的问题:在内部类AsyncTask的onPostExecute()中使用getString()而不使用周围Activity的上下文是否可以保存?

非常感谢提前。

public class MyActivity extends Activity {

    /* package */ MyActivity context;

    private class MyAsyncTask extends AsyncTask<Void, Void, Void> {

        public MyAsyncTask(final MyActivity context) {
            super();

            this.context = context;
        }

        @Override
        protected Cursor doInBackground(/* ... */) {
            // ...
        }

        @Override
        protected void onPostExecute(/* ... */) {
            if (context != null) {
                // Currently I do use that
                String s = context.getString(R.string.mytext);
                context.task = null;
            }

            // Would this be save?
            String s2 = getString(R.string.mytext);
        }

        @Override
        protected void onPreExecute (/* ... */) {
            // ...
        }
    }

    /* package */ MyAsyncTask  task;

    @Override
    public void onCreate(final Bundle bundle) {
        // ...

        Bundle bundleExtras = getIntent().getExtras();
        if (bundleExtras != null) {
            task = (MyAsyncTask) getLastNonConfigurationInstance();
            if (task != null) {
                task.context = this;
                // ...
            } else {
                task = new MyAsyncTask(this);
                task.execute();
            }
        }
    }

    @Override
    public Object onRetainNonConfigurationInstance() {
        if (task != null) {
            // ...
            task.context = null;
        }

        return task;
    }
}

2 个答案:

答案 0 :(得分:1)

您正在使用MyAsyncTask()指针初始化this的实例:

task = new MyAsyncTask(this);

onPostExecute中,您正在访问使用提供的指针初始化的类成员context。您的上下文是封闭类的上下文,即MyActivity

答案 1 :(得分:1)

  

是否可以在内部类AsyncTask的onPostExecute()中使用getString()而不使用周围Activity的上下文?

不,这不安全。作为该活动的内部课程,您的MyAsyncTask课程在创建时会引用MyActivity。因此,如果MyActivity由于任何原因(例如轮换)而被杀死,则在onPostExecute回调中,您最终将MyAsyncTask持有对已杀死MyActivity实例的引用。

使用对Activity的引用更安全,因为您更新该引用始终指向MyActivity的有效实例。也许您还希望使用Activity直接在onRetainNonConfigurationInstance中使null无效,以确保您不触及它(如果MyAsyncTask到达onPostExecute直到你有一个有效的引用,直到你再次设置MyActivity