Loader在Activity start confusion上重新启动

时间:2017-10-05 21:45:21

标签: android android-activity loader android-loadermanager android-loader

我有一台装载机。我希望它只在基础数据模型发生变化时才开始。我理解为装载机的重点。来自Android文档:

  

加载器,特别是CursorLoader,应该保留它们的数据   被阻止后这允许应用程序保留其数据   跨越活动或片段的onStop()和onStart()方法,所以   当用户返回应用程序时,他们不必等待   要重新加载的数据。

大。但是,每当我的活动恢复时,我的加载器onStartLoading()都会被调用。调试到平台代码,Activity.onStart()的实现最终重新启动所有的加载器。具体来说,调用堆栈是

Activity.onStart() -->
FragmentController..doLoaderStart() -->
FragmentHostCallback.doLoaderStart() -->
LoaderManagerImpl.doStart() --> 
LoadermanagerImpl.LoaderInfo.start() -->
Loader.startLoader() -->
<my loader>.onStartLoading()

我的加载程序成本很高,所以当我的活动重新启动时,我不希望它重新加载,这似乎与上面的引用相反,后者明确指出加载器应该在停止/启动周期中保留其数据。

这有意义吗?

1 个答案:

答案 0 :(得分:3)

回答自己。

问题基本上是对装载机的误解。当框架调用Loader的{​​{1}}时,它更像是生命周期方法。这是告诉您的加载器活动已经开始的框架。与我原来的想法相反,这并不意味着加载器必须重新加载它的数据。

加载器的天真实现(比如我的)只需在onStartLoading()上重新加载所有数据。只有在底层数据发生变化时才会加载更智能的实现。如果我们查看onStartLoading()

CursorLoader.onStartLoading()

如果有的话,它会立即发送缓存的结果。然后调用实际加载数据的@Override protected void onStartLoading() { if (mCursor != null) { deliverResult(mCursor); } if (takeContentChanged() || mCursor == null) { forceLoad(); } } ,但只有在数据发生变化时才会执行此操作

其他细节是内容更改时的跟踪方式。归结为forceLoad() Loader的实施:

onContentChanged()

此方法说:当内容在我们启动时发生更改时,请加载数据。否则,只需保留一个标志,告诉我们内容已更改。它基本上是在延迟加载器启动之前延迟数据的实际负载。

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; } } 基本上检查takeContentChanged()实例字段:

mContentChanged

只要您的加载器实现在内容发生变化时调用public boolean takeContentChanged() { boolean res = mContentChanged; mContentChanged = false; mProcessingChange |= res; return res; } onContentChanged()的实现就会处理剩下的内容。