【问题标题】:How Does AsyncTaskLoader Cache Data?AsyncTaskLoader 如何缓存数据?
【发布时间】:2012-07-31 23:44:26
【问题描述】:

我有一个活动,它实现了所有这些代码所在的片段。这最好通过一个例子来解释,因为代码是保密的。这个例子反映了我正在尝试做的事情以及我通过测试观察到的事情

例如)我有一个 rss 阅读器片段,它从两个具有加载器 ID(加载器 1、加载器 2)的唯一加载器中获取两个唯一对象(A、B)

Object A: 

int[] fullArticleIdList;
List<ArticlePreview> partialArcticlePreviewList;

Object B:

List<ArticlePreview> partialArcticlePreviewList;

在创建时,我在加载器 1 上调用“initloader”来获取对象 A。滚动浏览可用文章后,它会到达从对象 A 返回的 partialArcticlePreviewList 的底部,并使用“加载器 2 上的重新启动加载器”获取更多文章,该加载器获取对象 B 和允许用户阅读它们并继续对所有文章执行此操作。

这工作正常,直到用户旋转设备从而调用 onCreate。现在当在 Loader 1 上调用 initloader 时,它在连接到 loader 1 后立即跳转到 onLoadFinished 并返回一个 Loader 1。虽然 articleIds 正确返回,但返回的 partialArcticlePreviewList 是 Loader 2 中获取对象 B 的那个。

加载器管理器是否只在缓存中保留一个对象实例并在多个加载器之间共享它?从广泛的测试(5 多个小时试图找到问题并查看 Eclipse 调试器中的加载程序 ID/缓存/地址)看来,它用加载程序 2 的部分内容预览列表中收到的数据覆盖了加载程序 1 的部分内容预览列表。虽然这种情况对于单个加载器来说是理想的,但我原以为每个加载器的缓存都是独立的。显然,加载程序的优点之一是它们易于使用,并且通过屏幕旋转和数据缓存实现持久性,但它似乎并没有像暗示的那样工作。我们通过保留片段的实例并在 onCreateView 和 onDestroyView 中编写适当的代码来规避该问题以避免内存泄漏,但这是一个好的解决方案吗?

编辑:忘记添加了,我们使用的是兼容性库 v4。此外,查看加载程序的 android 源代码似乎并没有说明加载程序为何返回错误数据的“mId”。

【问题讨论】:

    标签: android android-fragments asynctaskloader


    【解决方案1】:

    用来规避这个问题的最终解决方案是简单地自己管理数据,而不是依赖加载器。

    加载器在只为一个屏幕加载一个东西时可以很好地保留数据,但是对于分页,他们创造了所有这些麻烦并且他们的操作方式仍然没有被很好地理解;结论是它们没有按预期运行,或者我们的实现有缺陷,这只会在更高级的用例中变得明显。

    为了自己管理数据,我们使用了捆绑包/保留片段的组合,同时小心地在 onDestroyView 中正确清理所有内容。我们还让加载器在旋转后执行回调时检查我们的数据集是否已经包含数据,因此我们不会将分页数据两次添加到数据集中。另一种选择是使用单例对象。

    希望这对将来的其他人有所帮助。

    【讨论】:

    • 我已经尝试解决这个问题一周了,你有我能看到的示例代码吗?谢谢!。
    • 我没有代码,但你可以试试stackoverflow.com/questions/7181526/…。基本上只是使用 asynctaskloader 来获取数据并将其存储在一个 parcel-able 中,然后在后续回调中忽略 asynctaskloader。然后将 parcelable 用于正常的生命周期条件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-01
    • 1970-01-01
    相关资源
    最近更新 更多