我一直在使用Android中的AsyncTasks,遇到了一个问题。
拿一个简单的例子来说,一个Activity只有一个AsyncTask。该任务在后台并没有做什么特别的事情,只是休眠8秒钟。
在AsyncTask的onPostExecute()方法结束时,我只是将一个按钮的可见性状态设置为View.VISIBLE,以验证我的结果。
现在,这很好用,直到用户在AsyncTask工作时(在8秒睡眠窗口内)决定更改他的手机方向。
我理解Android活动生命周期,我知道活动会被销毁并重新创建。
这就是问题所在。AsyncTask正在引用一个按钮,并且显然保留对首次启动AsyncTask的上下文的引用。
我期望,这个旧的上下文(因为用户导致了方向的改变)要么变为null并使AsyncTask引发NPE,因为它试图使按钮可见;
相反,没有抛出NPE,AsyncTask认为按钮引用不为null,将其设置为可见。结果?屏幕上什么也没有发生!
更新:我通过保持对活动的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);
}
}
}
在执行此操作时,当异步任务正在工作时,请尝试更改手机的方向。