Android 加载程序在活动开始时重新启动

Android 加载程序在活动开始时重新启动,android,android-activity,loader,android-loadermanager,android-loader,Android,Android Activity,Loader,Android Loadermanager,Android Loader,我有一个加载器。我希望它只在底层数据模型更改时启动。我把它理解为装载机的一个点。从Android文档: 加载器,尤其是游标加载器,需要保留其数据 在被阻止之后。这允许应用程序保留其数据 在活动或片段的onStop()和onStart()方法中 当用户返回应用程序时,他们不必等待 要重新加载的数据 太好了。但是,每当我的活动恢复时,就会调用我的加载程序onStartLoading()。通过调试平台代码,Activity.onStart()的实现最终会重新启动所有加载程序。具体来说,调用堆栈是 Ac

我有一个加载器。我希望它只在底层数据模型更改时启动。我把它理解为装载机的一个点。从Android文档:

加载器,尤其是游标加载器,需要保留其数据 在被阻止之后。这允许应用程序保留其数据 在活动或片段的onStop()和onStart()方法中 当用户返回应用程序时,他们不必等待 要重新加载的数据

太好了。但是,每当我的活动恢复时,就会调用我的加载程序onStartLoading()。通过调试平台代码,Activity.onStart()的实现最终会重新启动所有加载程序。具体来说,调用堆栈是

Activity.onStart() -->
FragmentController..doLoaderStart() -->
FragmentHostCallback.doLoaderStart() -->
LoaderManagerImpl.doStart() --> 
LoadermanagerImpl.LoaderInfo.start() -->
Loader.startLoader() -->
<my loader>.onStartLoading()
Activity.onStart()-->
FragmentController..doLoaderStart()-->
FragmentHostCallback.doLoaderStart()-->
LoaderManagerImpl.doStart()-->
LoadermanagerImpl.LoaderInfo.start()-->
Loader.startLoader()-->
.onStartLoading()
我的加载程序成本很高,所以我不希望在我的活动重新启动时重新加载它,这似乎与上面的引文相反,上面的引文特别指出加载程序应该在停止/启动周期之间保留其数据

这有意义吗?

回答我自己

问题基本上是对装载机的误解。当框架调用
加载程序
onStartLoading()
时,它更像是一种生命周期方法。它是告诉加载程序活动已经开始的框架。与我最初的想法相反,这并不意味着加载器必须重新加载它的数据

加载程序(如我的)的简单实现只是在
onStartLoading()
上重新加载它的所有数据。只有在基础数据发生更改时,才会加载更智能的实现。如果我们看一下CursorLoader.onStartLoading()

它首先立即发送缓存结果(如果有)。然后调用实际加载数据的
forceLoad()
,但仅当数据发生更改时才会执行此操作

另一个细节是当内容发生变化时如何跟踪。它归结为
Loader
onContentChanged()
的实现:

此方法表示:当内容在开始时发生更改时,加载数据。否则,只需保留一个标志,让我们知道内容已更改。它基本上是延迟数据的实际加载,直到加载程序启动

takeContentChanged()
基本上检查
mContentChanged
实例字段:

public boolean takeContentChanged() {
    boolean res = mContentChanged;
    mContentChanged = false;
    mProcessingChange |= res;
    return res;
}

只要您的加载程序实现在内容发生更改时调用
onContentChanged()
,则
loader
的实现将处理其余部分。

只是一个提示。您应该真正考虑使用生命周期组件,而不是加载程序。这是一篇关于加载器、生命周期和状态的精彩文章:你能分享一下你在哪里调用
getLoaderManager.initLoader()
?甚至还有一个方法可以帮助你调试加载器代码,但是,我们需要看看你在哪里调用
initLoader()
/
restartLoader()
,如果它是一个自定义加载器,加载程序本身的代码。
public void onContentChanged() {
    if (mStarted) {
        forceLoad();
    } else {
        // This loader has been stopped, so we don't want to load
        // new data right now...  but keep track of it changing to
        // refresh later if we start again.
        mContentChanged = true;
    }
}
public boolean takeContentChanged() {
    boolean res = mContentChanged;
    mContentChanged = false;
    mProcessingChange |= res;
    return res;
}