使用 LoaderManager 加载依赖查询的首选方法
Posted
技术标签:
【中文标题】使用 LoaderManager 加载依赖查询的首选方法【英文标题】:Preferred method of loading dependent queries with LoaderManager 【发布时间】:2015-10-29 01:28:29 【问题描述】:在 android 中使用 LoaderManager API 加载依赖查询的首选方法是什么?到目前为止,我能想到的最好的方法是:
@Override
public void onCreate( Bundle savedInstanceState )
getLoaderManager().initLoader( FIRST, null, this );
@Override
public void onLoadFinished( Loader<Cursor> loader, Cursor data )
switch ( loader.getId() )
case FIRST:
Bundle args = new Bundle();
args.putInt( ID, somethingFromData( data ) );
getLoaderManager().restartLoader( SECOND, args, this );
break;
case SECOND:
somethingElseFromData( data );
break;
这在大多数情况下都可以正常工作,但在一种特殊情况下会严重崩溃。假设我启动第二个活动或在此之上推送一个片段,以修改 FIRST
的数据。现在,当我使用上面的代码导航回活动/片段时,它首先用FIRST
和SECOND
的旧数据刷新我,并且由于FIRST
启动SECOND
,SECOND
重新加载了新数据.现在,由于 FIRST
已更改,它会再次加载,这会导致再次加载 SECOND
。
首先,如果你算上这两个负载FIRST
(一个旧的和一个新的)和三个负载的SECOND
(两个旧的和一个新的),这至少有点浪费。我真的不介意,除了调试很麻烦,但在我看来,它的行为也是不确定的,因为你不知道哪些负载会先完成。如果FIRST
和SECOND
之间的关系发生变化,我会得到SECOND
的新数据,还是会得到缓存的值?
我知道我可以通过记录何时重新启动第二个加载程序来缓解这种情况,但必须有更好的方法来做到这一点。
澄清一下:如果FIRST
中的行包含对SECOND
中行的引用,并且在返回导航后FIRST
中加载的行不指向同一行,则问题最为突出(s) SECOND
和以前一样。
【问题讨论】:
不知道你的数据是什么样的,但它闻起来像数据库视图可能会有所帮助并允许你只使用一个加载器? 这与子查询、连接等不是一回事吗?更新方式是否与其他查询相同? IE。SELECT first.id, second.id FROM first JOIN second ON first.id = second.first
,第一个或第二个被编辑了,我会从LoaderManager
得到新的更新吗?
我具体想到的示例:sqlfiddle.com/#!5/3dd28/2/0
一些带有异常堆栈跟踪的 logcat 输出会有所帮助
怎么样?这不是段错误或类似错误,logcat 中也没有任何有用的信息。我正在寻求最知名的方法来解决问题,而不是寻求崩溃的帮助。
【参考方案1】:
鉴于您的第一个加载器所做的唯一事情就是为您的第二个加载器有效地准备参数,您应该将自己的 AsyncTaskLoader 子类化并在一个加载器中完成整个操作。
This article 包含一个非常深入的自定义 AsyncTaskLoader 示例,我相信您可以根据自己的需要进行调整。您还应该查看CursorLoader source code 以更好地掌握如何编写自己的代码。
【讨论】:
你的意思是这个:developer.android.com/reference/android/content/…?您的链接已损坏。而且看起来你有中文网站什么的。 是的,我做到了!对不起!当我用谷歌搜索 android 的东西时,中文网站出现了.. 真的不知道为什么 出于某种原因,它也为我这样做。我认为谷歌在他们的语言设置上搞砸了。 =) 这个 AsyncTaskLoader 解决方案;如果像 LoaderManager 一样更新数据库,它会自动加载新结果吗? 非常想看两个。 =) 谢谢。下次我解决这个问题时,我会尝试这个解决方案(可能在几周内,目前正忙于其他事情^^,)如果它有效,如果之前没有更好的出现,我会接受你的回答那。 =D以上是关于使用 LoaderManager 加载依赖查询的首选方法的主要内容,如果未能解决你的问题,请参考以下文章
用于在多个活动/片段中重用的全局加载器 (LoaderManager)
Android-LoaderManager异步加载数据库数据