Android:如何在Activity被销毁时保留AsyncTask实例?

时间:2012-08-04 20:00:13

标签: android android-asynctask

在我的应用程序中,我有一个继承自AsyncTask并从服务器下载大量数据的类。我使用ProgressBar来表示下载的进度。

当用户点击HOME密钥时,此Activity所附加的AsyncTask将被销毁,但下载继续进行。

如何重新附加此AsyncTask并向用户显示进度?我尝试使用onRetainNonConfigurationInstance,但Android 4.0似乎没有调用此方法。我的应用程序不使用Fragments API。

3 个答案:

答案 0 :(得分:4)

我在这种情况下所做的如下:

  1. 我创建了一个IntentService来处理与服务器的通信。这具有AsyncTask的一些好处(例如,工作线程),但也有服务的一些好处(随时随地可用)。
  2. 可以通过我的主Activity中的用户操作或inexact repeating alarm来调用IntentService。
  3. 数据存储在SQLite database中,前面是ContentProvider。我通过使用SQLiteOpenHelper并从我的后台IntentService的安全性调用getWritableDatabase()来解决何时/如何创建我的数据库和表的问题。
  4. 任务完成后,如果我的主要活动未激活,则会发布Notification
  5. 这种安排的一个好处是,不需要进度条。实际上,没有必要使用UI。用户在服务运行时继续使用应用程序,当新数据进入ContentProvider时,UI会自动刷新自身。另一个不错的方面是它编写的代码比AsyncTask少。它通过从数据库中读取最后一个条目的服务器端元数据并要求用户在该点之后启动,自动获取它最后停止的位置。由于它与任何Activity实例无关,因此它不关心onPostExecute()configuration changes或其中任何一个。而且您不必担心像AsyncTask这样的单次执行。

答案 1 :(得分:1)

如果需要在后台下载大量数据,我会使用服务而不是AsyncTask。 Google IO对于使用服务有一个很好的presentation

引自AsyncTask文档:

  

如果你需要保持线程长时间运行,那就是   强烈建议您使用提供的各种API   java.util.concurrent pacakge如Executor,ThreadPoolExecutor和   FutureTask。

  

该任务只能执行一次(如果尝试第二次执行则会抛出异常。)

据我了解,您无法继续使用上一次AsyncTask。 仍然,您可以部分加载数据并节省读取的数据量,然后启动新的AsyncTask,它将从上次保存的点开始。从我的观点来看,当活动进入后台时暂停加载并不是最好的想法,最好使用服务来完成开始的工作。

答案 2 :(得分:0)

您是否考虑过使用服务将AsyncTask附加到?看作永久运行的服务可能是您手头任务的最佳解决方案。那么您所要做的就是检查服务是否正在运行以及您的下载是否正在运行(使用静态布尔变量轻松完成)然后您只需使用服务中的某个状态保存变量创建进度对话框(可能是一个百分比)在主要活动的onCreate方法中,已下载的文件总大小等)。