【问题标题】:AsyncTaskLoader is reset when device is rotated while the app is stoppedAsyncTaskLoader 在应用程序停止时旋转设备时重置
【发布时间】:2015-04-08 00:05:17
【问题描述】:

我有一个 AsyncTaskLoader 在非常特殊的情况下被重置,希望有人能告诉我原因。

  1. 在我的活动中,我在onCreate() 方法中调用getSupportLoaderManager().initLoader(0, null, this)。一切都按预期运行:
D/Activity﹕ calling initLoader()
D/Activity﹕ onCreateLoader()
D/Loader﹕ onStartLoading()
D/Loader﹕ onStartLoading(): no data, forcing load
D/Loader﹕ loadInBackground()
D/Activity﹕ onLoadFinished()
  1. 但是,如果我将应用程序置于后台(点击主页),旋转设备,然后将其返回到前台,我会看到加载器已重置:
D/Activity﹕ onLoaderReset()
D/Activity﹕ calling initLoader()
D/Activity﹕ onCreateLoader()
D/Loader﹕ onStartLoading()
D/Loader﹕ onStartLoading(): no data, forcing load
D/Loader﹕ loadInBackground()
D/Activity﹕ onLoadFinished()

当应用程序被发送到后台并恢复(以相同的方向)时,加载程序不会重置,并且当应用程序在前台时旋转设备时,加载程序不会重置。因此,我不希望它在 #2 中描述的情况下被重置。

谁能提供任何见解?我试图阻止应用程序在有人将应用程序设置为背景、旋转设备然后恢复应用程序的关闭更改中进行不必要的调用。谢谢

【问题讨论】:

  • 发生这种情况时是否还会调用 OnCreate()?
  • 是的,正在调用 onCreate()
  • 好吧,由于某种原因,您的活动正在重新创建。您应该在代码中考虑这种情况。我会发布答案
  • 活动在旋转时被销毁并重新创建。这是正常的,也是意料之中的。问题是当应用程序不可见时,加载程序会被重置。

标签: android asynctaskloader


【解决方案1】:

有时设备会破坏活动,然后在用户返回时将其恢复。您需要在重新创建状态时恢复您的状态。如果您有需要保存的变量,则需要覆盖此方法:

    @Override
    public void onSaveInstanceState (Bundle outState) {
        // save you variables
        outState.putInt("myInt", myInt);
    }

因此,当重新创建活动时,您将检查 savedInstanceState 是否为空。如果它为空,你可以像往常一样初始化,如果不是,你可以恢复你的状态。对于您的情况,如果 savedInstanceState 不为空,您将不会初始化加载器

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if(savedInstanceState != null) {
        // restore state
    } else {
        // init your loader
    }

}

【讨论】:

  • 这并没有回答有关加载程序被重置的问题。
【解决方案2】:

这个问题仍然悬而未决,所以这是我的答案。我尝试了您的用例 (2),但我的 AsyncTaskLoader 没有重置。请注意,我还重写了回调以保存 App Instance 状态。

如果您已正确初始化加载程序,我怀疑您可能没有保存 App Instance 状态。 当您将应用程序发送到后台时,这向 Android 系统表明您的应用程序可能已被破坏。即使它已暂停,Android 系统也可以根据系统的资源、当前负载和许多其他条件做出决定,将其从暂停状态移动到停止状态并释放资源。这就是您的情况可能发生的情况。

无论如何,这就是我使用加载器功能的方式。有 initLoader() 和 restartLoader()。

使用 initLoader() 您需要在调用它之前进行检查,使用 restartLoader() 您需要将 Bundle 传递给调用。

所以

if(getSupportLoaderManager().getLoader(0) != null)
  {
    getSupportLoaderManager.initLoader(0,null,this);
  }

对于全新的重启

   Bundle mybundle = new Bundle();
   mybundle.putString("somekey", "someval");
   getSupportLoaderManager.restartLoader(0,mybundle,this);

我假设 AsyncTaskLoader 设置和 Loader 回调的实现已正确完成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-20
    • 1970-01-01
    • 2012-06-15
    • 1970-01-01
    • 2013-02-07
    相关资源
    最近更新 更多