我在我的活动中使用了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的静态全局类中?
由于
答案 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;
}
}