OnLoadFinished() 调用了两次

Posted

技术标签:

【中文标题】OnLoadFinished() 调用了两次【英文标题】:OnLoadFinished() called twice 【发布时间】:2013-01-21 02:30:59 【问题描述】:

我想弄清楚我是否在加载程序方面做错了什么。我正在使用支持库,并且我有一个片段,它在 onCreate() 调用 initLoader() 将自身设置为 LoaderCallbacks,但是在旋转时,它在 onLoadFinished() 中收到两次结果,一次是由于调用 init (并且它已经拥有数据),并且由于 FragmentActivity 循环遍历 onStart() 中的所有加载器并传递结果,因为它已经拥有数据。

如果我只调用一次 init(在 Fragment 首次启动时),它不会将自己设置为 Loader 的回调,因此它根本不会收到对 onLoadFinished 的调用。似乎 onLoadFinished 应该只被调用一次,因为一些昂贵的事情可能会在 onLoadFinished() 中完成(例如清除列表适配器等),所以我只是想弄清楚这是一个错误还是我是只是在错误的时间调用 init 或其他什么。

有人对此问题有任何见解吗?

【问题讨论】:

我不确定为什么会发生这种情况,但在onResume() 中调用getLoaderManager().initLoader(0, null, this); 似乎是很多人(包括我)的解决方案。见***.com/a/14524031/1617737。 这是我找到的最佳答案:***.com/a/17324776/2578070 【参考方案1】:

我遇到了类似的问题,原因是我的代码中有initLoaderrestartLoader。根据用户的操作,我的查询可能会更改,因此我需要重新启动加载程序。

解决方案是仅使用restartLoader,即使在onResume 回调方法中将initLoader 替换为restartLoader

【讨论】:

【参考方案2】:

这是一个相当古老的问题,但对于未来的读者,我有一个替代解决方案。基本上我最终做的是重新启动加载器(如果存在)。

public void onActivityCreated(Bundle savedInstanceState) 
...
       if(getLoaderManager().getLoader(Constants.LOADER_ID) == null) 
            getLoaderManager().initLoader(Constants.LOADER_ID, null, this);
         else 
            getLoaderManager().restartLoader(Constants.LOADER_ID, null, this);
        

...

这解决了我在屏幕上旋转加载程序被触发两次的问题。还有一点需要注意的是,这只对我测试过的 android

【讨论】:

此解决方案可能有效,但与前面提到的 Alex Lockwood 存在相同的问题。【参考方案3】:

我自己也遇到了同样的问题,没有好的解决方案。 它似乎是 Android 框架中的错误,这里是类似的线程,其中建议的解决方案是将 initLoader() 放在 onResume() 中 - 我已经尝试过它并且它有效,onLoadFinished() 只被调用一次: Android: LoaderCallbacks.OnLoadFinished called twice

【讨论】:

【参考方案4】:

在Android: LoaderCallbacks.OnLoadFinished called twice查看我的帖子

在 ViewPager 中重新启动 Fragments 时,我遇到了类似的问题。我的解决方案是在完成加载程序后(在 onLoadFinished 结束时)通过调用删除加载程序

getLoaderManager().destroyLoader(LOADER_ID);

希望对你有帮助!

【讨论】:

这是一个非常糟糕的解决方案...销毁Loader 也会销毁与其关联的所有数据。 Loaders 的主要优点之一是数据在配置更改(例如方向更改等)时保留...销毁此数据意味着您需要在每次配置更改时重新查询数据。 【参考方案5】:

看起来像框架加载器错误的实现/错误。 1. 看看我从屏幕旋转后每个重要方法/回调的 Log.v(LOG_TAG, ...) 消息中得到了什么:

...: .initLoader() 100
...: onStartLoading()
...: onLoadFinished()
...: updateUi(); articles size=10
...: loadInBackground()
...: getInputStream() - HttpRequest
...: onLoadFinished()
...: updateUi(); articles size=10

2. 正如你所见,'updateUi()' 之后的所有内容都不需要了。

【讨论】:

以上是关于OnLoadFinished() 调用了两次的主要内容,如果未能解决你的问题,请参考以下文章

didUpdateToLocation 调用了两次,好的。为啥 oldLocation 两次都为零?

为啥片段恢复后再次调用onLoadFinished?

ViewDidLoad 调用了两次

didRegisterUserNotificationSettings 被调用了两次?

ListSelectionListener 调用了两次

Cedar - 检查是不是使用不同的值调用了两次方法