使用 LoaderManager 的多个加载器的模式?
Posted
技术标签:
【中文标题】使用 LoaderManager 的多个加载器的模式?【英文标题】:Pattern for multiple Loaders with LoaderManager? 【发布时间】:2012-03-07 10:57:17 【问题描述】:我正在使用 Fragments 和 LoaderManager。我必须启动未知数量的任务,它们可能会并行运行(否则我只会重用一个且只有一个加载器)。例如,我有一个列表视图,每一行可能都有一个按钮来将该行的内容保存到网络服务器。用户可以同时对多个项目发起保存请求。
private int nextId = 0;
private void onClickListener()
Bundle bundle = new Bundle();
bundle.putNextData(...);
getLoaderManager().initLoader(nextId++, bundle, this);
我可以尝试自己记账,所以手动创建一个加载器池并在可能的情况下重用它们,看起来它可能已经被 API 实现了?
谢谢
【问题讨论】:
好问题。你设法解决了吗?我认为你应该以某种方式排队你的任务。 【参考方案1】:我认为您不应该使用 Loader 将数据保存到远程服务器。
改为使用IntentService
或类似的东西来处理“保存”操作队列。这样一来,您与网络服务器的通信可以被批处理、折叠(即,单个项目的多个排队保存可以折叠到一个操作中),并且如果需要,将超出您的活动生命周期。
由IntentService
(或等效项)处理的保存队列也是使用退避重试失败操作的好方法,因为您可以使用AlarmManager
实现具有指数退避的延迟重试。
【讨论】:
如果我在数据库中有n
类别,我想使用CursorLoader
加载它们。我应该使用什么 ID?
您当然可以使用任意 ID,如果类别是静态的,可能只使用整数 1..n。如果您首先加载类别列表,然后加载每个类别的详细信息,那么您可能需要优化查询。但是假设您没有其他选择,您应该使用稳定的 id 作为 Loader id,而不是例如光标位置。【参考方案2】:
IntentService 或绑定服务始终是解决此问题的好方法。 正如 Roman 指出的那样,请注意,不强烈建议将多个请求排入队列并分别调用它们(很有可能您在无线电连接上做了大量工作 - 在使用数据时 - 这会耗尽您的电池。这里是 @987654321 @关于那个)
我个人建议使用具有请求队列和可用线程池的绑定服务(这种方法可以让您完全控制更复杂的网络操作,例如您的情况)。有更多关于here 方法的详细信息以及here 上的测试用例工作示例。
向我们更新您的进度。
【讨论】:
【参考方案3】:你的方向是对的,让我帮你一点。
重用确实是个好主意,您不必担心,因为 android 已经为您做到了(实际上是 Java ;)
它称为ThreadPoolExecuter,您可以启动任意数量的任务,并且他只会打开预定义数量的线程。(最佳实践是尝试打开尽可能多的线程,因为可以在设备上运行并行网络连接。根据我的研究,它在 4 - 9 之间)。
如果您尝试两次下载相同的 URL,您可以保护自己并只为它打开一个任务。
【讨论】:
以上是关于使用 LoaderManager 的多个加载器的模式?的主要内容,如果未能解决你的问题,请参考以下文章