Android AsyncTask 上下文行为 [英] Android AsyncTask context behavior

本文介绍了Android AsyncTask 上下文行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!


我一直在使用 Android 中的 AsyncTasks,但我正在处理一个问题.

I've been working with AsyncTasks in Android and I am dealing with an issue.

举一个简单的例子,一个带有一个 AsyncTask 的 Activity.后台的任务没有做任何壮观的事情,它只是休眠了 8 秒.

Take a simple example, an Activity with one AsyncTask. The task on the background does not do anything spectacular, it just sleeps for 8 seconds.

在 onPostExecute() 方法中的 AsyncTask 结束时,我只是将按钮可见性状态设置为 View.VISIBLE,只是为了验证我的结果.

At the end of the AsyncTask in the onPostExecute() method I am just setting a button visibility status to View.VISIBLE, only to verify my results.

现在,这很好用,直到用户决定在 AsyncTask 工作时(在 8 秒睡眠窗口内)改变他的手机方向.

Now, this works great until the user decides to change his phones orientation while the AsyncTask is working (within the 8 second sleep window).

我了解 Android Activity 生命周期,并且我知道 Activity 会被销毁和重新创建.

I understand the Android activity life cycle and I know the activity gets destroyed and recreated.

这就是问题所在.AsyncTask 指的是一个按钮,并且显然持有对首先启动 AsyncTask 的上下文的引用.

This is where the problem comes in. The AsyncTask is referring to a button and apparently holds a reference to the context that started the AsyncTask in the first place.

我希望,这个旧的上下文(因为用户导致方向改变)要么变为空,要么 AsyncTask 抛出一个 NPE 以引用它试图使其可见的按钮.

I would expect, that this old context (since the user caused an orientation change) to either become null and the AsyncTask to throw an NPE for the reference to the button it is trying to make visible.

相反,没有抛出 NPE,AsyncTask 认为按钮引用不为空,将其设置为可见.结果?屏幕上什么都没有发生!

Instead, no NPE is thrown, the AsyncTask thinks that the button reference is not null, sets it to visible. The result? Nothing is happening on the screen!

更新:我已经解决了这个问题,方法是将 WeakReference 保留到 Activity 并在发生配置更改时进行切换.这很麻烦.

Update: I have tackled this by keeping a WeakReference to the activity and switching when a configuration change happens. This is cumbersome.


public class Main extends Activity {

    private Button mButton = null;
    private Button mTestButton = null;

    public void onCreate(Bundle savedInstanceState) {

        mButton = (Button) findViewById(;
        mButton.setOnClickListener(new OnClickListener () {
            public void onClick(View v) {
                new taskDoSomething().execute(0l);
        mTestButton = (Button) findViewById(;   

    private class TaskDoSomething extends AsyncTask<Long, Integer, Integer> 
        protected Integer doInBackground(Long... params) {
            Log.i("LOGGER", "Starting...");
            try {
            } catch (InterruptedException e) {
            return 0;

        protected void onPostExecute(Integer result) {
            Log.i("LOGGER", "...Done");

尝试执行它,并在 AsyncTask 工作时更改您的手机方向.

Try executing it and while the AsyncTask is working change your phones orientation.


AsyncTask 并非设计为在 Activity 被拆除并重新启动后重用.就像您所说的那样,内部 Handler 对象变得陈旧.在 Romain Guy 的 Shelves 示例中,他简单地取消了当前正在运行的所有 AsyncTask,然后在方向更改后重新启动新的.

AsyncTask is not designed to be reused once an Activity has been torn down and restarted. The internal Handler object becomes stale, just like you stated. In the Shelves example by Romain Guy, he simple cancels any currently running AsyncTask's and then restarts new ones post-orientation change.


It is possible to hand off your Thread to the new Activity, but it adds a lot of plumbing. There is no generally agreed on way to do this, but you can read about my method here :

这篇关于Android AsyncTask 上下文行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

登录 关闭
发送“验证码”获取 | 15天全站免登陆