我确实在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;
}
}
答案 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
。