【问题标题】:Android How to reconnect to AsyncTask after onDestroy() and relaunch onCreate()?Android 如何在 onDestroy() 后重新连接到 AsyncTask 并重新启动 onCreate()?
【发布时间】:2012-05-21 16:22:17
【问题描述】:

我已经测试了 AsyncTasks 不会随着它们的启动活动而被破坏的声明。这是真的

我让 AsyncTask 每 3 秒发布一条 Log.i() 消息,持续 1 分钟。并且我将Log.i() 消息放在活动的onDestroy() 方法中。

我看到活动被破坏了,但 AsyncTask 继续运行,直到它完成所有 20 条 Log.i() 消息。

我很困惑。

  1. 如果 AsyncTask 将 publishProgress() 放入已破坏的 UI 会怎样?
    我猜会发生某种异常,对吧?

  2. 如果 AsyncTask 将数据存储在 class Application 的全局变量中怎么办?
    这里不知道,NullPointer 异常?

  3. 如果应用重新启动会怎样?
    它可能会启动一个新的 AsyncTask。它可以与仍在运行的 AsyncTask 重新连接吗?

  4. 母应用销毁后,AsyncTask 是否不死?
    也许是的,所有 LogCat 应用程序如何在 UI 应用程序不再可见或被破坏时保持记录消息?当您重新打开它们时,它们会向您显示在它“死”时生成的消息。

这一切看起来像是一场讨论,但问题就在标题中。我有这个孤立的 AsyncTask,我非常想在重新启动应用程序时重新连接它,但我不知道该怎么做。

我忘了说明为什么这很重要。当方向发生变化时,应用程序会被破坏。而且我不想丢失 AsyncTask 产生的数据,我不想停止它并重新启动它。我只是希望它在方向更改完成后继续运行并重新连接。

【问题讨论】:

    标签: android android-asynctask lifecycle


    【解决方案1】:

    我希望我做对了,因为它来自一些我不再使用的旧代码(我现在使用 IntentService 来做以前做的事情)。

    这是我在我的主要Activity 中下载文件时最初拥有的...

    public class MyMainActivity extends Activity {
    
        FileDownloader fdl = null;
    
        ...
    
        // This is an inner class of my main Activity
        private class FileDownloader extends AsyncTask<String, String, Boolean> {
            private MyMainActivity parentActivity = null;
    
            protected void setParentActivity(MyMainActivity parentActivity) {
                this.parentActivity = parentActivity;
            }
    
            public FileDownloader(MyMainActivity parentActivity) {
                this.parentActivity = parentActivity;
            }
    
          // Rest of normal AsyncTask methods here
    
        }
    }
    

    关键是使用onRetainNonConfigurationInstance()来“保存”AsyncTask

    Override
    public Object onRetainNonConfigurationInstance() {
    
        // If it exists then we MUST set the parent Activity to null
        // before returning it as once the orientation re-creates the
        // Activity, the original Context will be invalid
    
        if (fdl != null)
            fdl.setParentActivity(null);
        return(fdl);
    }
    

    然后我有一个名为doDownload() 的方法,如果Boolean 指示downloadComplete 为真,则从onResume() 调用该方法。 Boolean 是在FileDownloaderonPostExecute(...) 方法中设置的。

    private void doDownload() {
        // Retrieve the FileDownloader instance if previousy retained
        fdl = (FileDownloader)getLastNonConfigurationInstance();
    
        // If it's not null, set the Context to use for progress updates and
        // to manipulate any UI elements in onPostExecute(...)
        if (fdl != null)
            fdl.setParentActivity(this);
        else {
            // If we got here fdl is null so an instance hasn't been retained
            String[] downloadFileList = this.getResources().getStringArray(R.array.full_download_file_list);
            fdl = new FileDownloader(this);
            fdl.execute(downloadFileList);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-09
      • 1970-01-01
      • 2020-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-25
      相关资源
      最近更新 更多