如何处理onPause()中的AsyncTask?

时间:2009-12-09 17:56:30

标签: android

我在我的活动中使用了AsyncTask。看起来像:

public class MyActivity {
    private AsyncTask mTask;

    private void doSomethingCool() {
        mTask = new AsyncTask(...);
        mTask.execute();
    }

    @Override
    protected void onPause() { 
        super.onPause();

        // How do I let the task keep running if just rotating?
        if (isFinishing() == false) {
            ... 
        }
    }
}

因此,如果用户正在旋转设备,则会调用onPause(),但我不想因此而取消任务。我知道有一种方法可以告诉系统实际上不会破坏我的旋转活动,但这是推荐用于此问题吗?我是否应该将AsyncTask放在一个不会绑定到Activity的静态全局类中?

由于

4 个答案:

答案 0 :(得分:5)

这增加了丹尼尔的答案,但是比评论中的字符更多。

通常情况下,当我使用AsyncTask时,我想要一个对话旋转,处理这个是荒谬的。你必须做的事情非常像Daniel链接到的线程中的解决方案。

基本原则是,让Task对象保持对其父对象的显式引用。跨屏幕旋转保持Task对象(使用onRetainNonConfigurationInstance),然后在onCreate中,确保如果任务存在且您来自屏幕旋转,请将Task的父活动设置为新实例。在任务内部,确保在显式父级上调用所有Activity方法。

您可以在此处看到我在基本ListActivity上执行此操作的示例: http://github.com/klondike/android-campfire/blob/master/src/com/github/klondike/android/campfire/RoomList.java

我做的一件事与那个例子不同的是,我将尽可能多地将Task的onPostExecute移动到Activity上的方法中,只是出于代码清洁的原因。

答案 1 :(得分:4)

在深入了解AsyncTask和方向更改的乐趣之前,让我首先问一下 - 你需要在变量中保留AsyncTask吗?你需要这么做的原因并不多,因为AsyncTask内置了回调函数,所以你实际上并不需要保留你的AsyncTask(不要打电话给他,他会打电话给你)。此外,即使在方向更改期间,您的AsyncTask仍应继续运行 - 毕竟它位于另一个线程中。

我唯一需要保留AsyncTask的是修复在AsyncTask运行时尝试显示Dialog时出现的错误。有一个修复,但它是非常讨厌的。有很多关于here的讨论,如果这是您遇到的具体问题。

答案 2 :(得分:1)

Click Here发送到android-developers listserv的一个很棒的帖子,其中包含一些关于在运行AsyncTask时处理屏幕转换或来电的信息。

由Mark Murphy撰写,来自http://commonsware.com/

他包含一个指向其中一个使用总线系统处理后台线程的项目的链接。 https://github.com/commonsguy/cwac-bus/tree

我最终在我的应用程序中实现了一些看起来很像post的东西,它运行得很好!

答案 3 :(得分:1)

如果你真的想要一直运行它: 我在从AsyncTask扩展的类中使用Singleton Pattern并在onResume中调用它:

@Override
protected void onResume() {
super.onResume();
// connection observer
if (!(AsyncTaskConnectionObserver.getInstance().getStatus() == AsyncTask.Status.RUNNING)) {
    AsyncTaskConnectionObserver.getInstance().execute();
}
}

我在onDestroy中什么都不做(是的,当你旋转时会调用它!)这个任务真的永远运行......

Singleton看起来像这样(只有结构,但我想你会得到它):

public class AsyncTaskConnectionObserver extends AsyncTask<Void, Void, Void> {

private AsyncTaskConnectionObserver(){
super();
}
/**
 * SingletonHolder is loaded on the first execution of
 * Singleton.getInstance() or the first access to SingletonHolder.INSTANCE,
 * not before.
 */
private static class SingletonHolder {
    public static final AsyncTaskConnectionObserver INSTANCE = new AsyncTaskConnectionObserver();
}

public static AsyncTaskConnectionObserver getInstance() {
    return SingletonHolder.INSTANCE;
}

}