我一直在使用 Android 中的 AsyncTasks,我正在处理一个问题。
举一个简单的例子,一个带有一个 AsyncTask 的 Activity。后台的任务没有做任何壮观的事情,它只是休眠了 8 秒。
在 onPostExecute() 方法中的 AsyncTask 结束时,我只是将按钮可见性状态设置为 View.VISIBLE,只是为了验证我的结果。
现在,这非常有效,直到用户决定在 AsyncTask 工作时(在 8 秒的睡眠窗口内)改变他的手机方向。
我了解 Android 活动的生命周期,并且知道活动会被销毁并重新创建。
这就是问题所在。 AsyncTask 指的是一个按钮,并且显然包含对首先启动 AsyncTask 的上下文的引用。
我希望,这个旧上下文(因为用户导致方向更改)要么变为空,并且 AsyncTask 抛出一个 NPE 以引用它试图使其可见的按钮。
相反,没有抛出 NPE,AsyncTask 认为按钮引用不为空,将其设置为可见。结果?屏幕上什么都没有发生!
更新:我已经通过保持WeakReference
活动并在配置更改发生时切换来解决这个问题。这很麻烦。
这是代码:
public class Main extends Activity {
private Button mButton = null;
private Button mTestButton = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mButton = (Button) findViewById(R.id.btnStart);
mButton.setOnClickListener(new OnClickListener () {
@Override
public void onClick(View v) {
new taskDoSomething().execute(0l);
}
});
mTestButton = (Button) findViewById(R.id.btnTest);
}
private class TaskDoSomething extends AsyncTask<Long, Integer, Integer>
{
@Override
protected Integer doInBackground(Long... params) {
Log.i("LOGGER", "Starting...");
try {
Thread.sleep(8000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 0;
}
@Override
protected void onPostExecute(Integer result) {
Log.i("LOGGER", "...Done");
mTestButton.setVisibility(View.VISIBLE);
}
}
}
尝试执行它并在 AsyncTask 工作时更改您的手机方向。