2012-08-02 88 views
2

我有一个活动,它实现了所有这些代码所在的片段。通过一个例子可以很好地解释这个问题,因为代码是保密的。这个例子反映了正在尝试做什么和通过测试我观察到了什么AsyncTaskLoader如何缓存数据?

例如)我有一个rss阅读器片段,它从两个独特的Loader(Loader 1,Loader2)中获取两个唯一对象(A,B) )

Object A: 

int[] fullArticleIdList; 
List<ArticlePreview> partialArcticlePreviewList; 

Object B: 

List<ArticlePreview> partialArcticlePreviewList; 

在创建我呼吁装载机1“initloader”的获取对象A.通过可用的文章滚动后它击中partialArcticlePreviewList从物体返回的底部和使用“restartloader装载机2取更多文章它读取对象B并允许用户阅读它们并继续为所有文章执行此操作。

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

加载器管理器是否只将对象的一个​​实例保存在缓存中并在多个加载器之间共享?看起来从广泛的测试(5个小时试图找到问题并查看Eclipse调试器中的加载器ID /缓存/地址),它使用它在Loader 2的partialArcticlePreviewList中收到的数据覆盖了Loader 1的partialArcticlePreviewList。虽然这种情况对于单个Loader来说是理想的,但我会认为每个Loaders的缓存都是独立的。显然装载者的优点之一是通过屏幕旋转和数据缓存的易用性和持久性,但它似乎并不像隐含的那样工作。我们通过保留片段的实例并在onCreateView和onDestroyView中编写适当的代码来避免内存泄漏,但这是一个很好的解决方案,从而绕过了这个问题?

编辑:忘了补充,我们正在使用兼容性库v4。另外,查看加载器的android源代码似乎没有揭示出为什么加载器为其“mId”返回错误数据的情况。

回答

3

用于规避此问题的最终解决方案仅仅是自己管理数据而不依赖装载器。

当他们只为屏幕加载一件东西时,加载程序很好地保留数据,但对于分页,他们创建了所有这些麻烦,而且它们的操作方式仍然没有很好理解;结论是,它们没有按预期运行,或者我们的实现有问题,只有在更高级的用例中才显现出来。

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

希望这可以帮助别人在未来。

+0

我一直试图解决这个问题一个星期了,你有没有我能看到的任何示例代码?谢谢!。 – 2014-07-29 21:50:02

+0

我没有代码,但你可以尝试https://stackoverflow.com/questions/7181526/example-of-implementing-parcelable。基本上只是使用asynctaskloader来获取数据并将其存储在一个最初的包中,然后在随后的回调中忽略asynctaskloader。然后可以将parcelable用于正常的生命周期条件。 – 2014-07-29 22:51:43