带 LoaderManager 的 CursorLoader 如何知道将光标发送到 CursorAdapter?
Posted
技术标签:
【中文标题】带 LoaderManager 的 CursorLoader 如何知道将光标发送到 CursorAdapter?【英文标题】:How does CursorLoader with LoaderManager know to send the cursor to a CursorAdapter? 【发布时间】:2012-06-24 10:01:36 【问题描述】:我正在浏览我的一些代码,我意识到我实际上并不知道CursorLoader
和LoaderManager
组合如何与CursorAdapter
连接一起使用。这是我感到困惑的部分。
agendaAdapter = new MyAgendaAdapter(this, null);
makeProviderBundle(new String[] "_id", "event_name", "start_date", "start_time",
"end_date", "end_time", "location", "date(?) >= start_date and date(?) <= end_date",
new String[]getChosenDate(), getChosenDate(), null);
getLoaderManager().initLoader(0, myBundle, MainDisplayActivity.this);
list.setAdapter(agendaAdapter);
那么我的自定义ContentProvider
中的query()
方法如何知道将其发送到特定的CursorAdapter
?我只是没有看到联系。我了解其中的所有其他内容,但这个问题是关于什么的。哦,我应该提一下,代码运行良好。
【问题讨论】:
我开始怀疑你问这些问题只是为了跟我开玩笑,因为我知道我忍不住回答(即使我在工作哈哈) idk 你在说什么 :) 但如果你在那里...... 【参考方案1】:首先,查看this post 和this post 的代码示例,以更深入地了解该过程的工作原理。
现在,回答您的问题...
我的自定义
ContentProvider
...中的query()方法如何?
首先要记住getContentResolver().query()
不会直接调用内容提供者的query
方法。您正在调用内容解析器的查询方法,该方法解析Uri
,确定您希望调用的提供程序,然后然后调用您的提供程序的query
方法.
查询如何发送到特定的
CursorAdapter
?
我将以API Demos 为例向您介绍整个过程。请注意,API 演示使用 ListFragment
而不是 ListActivity
(在此问题的上下文中差异并不重要)。
首先,创建(并设置)CursorAdapter
。
mAdapter = new SimpleCursorAdapter(
getActivity(),
android.R.layout.simple_list_item_2,
null,
new String[] Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS ,
new int[] android.R.id.text1, android.R.id.text2 ,
0);
执行此语句后,SimpleCursorAdapter
知道它应该如何将游标数据与您的视图相关联。光标的Contacts.DISPLAY_NAME
列中的任何数据都将与id 为android.R.id.text1
等的视图相关联。
请注意,您已将 null
游标作为第三个参数传递给构造函数。这非常重要,因为我们还没有查询任何数据(这是LoaderManager
和CursorLoader
的工作)。
接下来,初始化加载器。
getLoaderManager().initLoader(0, null, this);
这告诉LoaderManager
创建并启动对应于id 0
的Loader
。
LoaderManager
调用onCreateLoader(int id, Bundle args)
。
onCreateloader
返回Loader<Cursor>
接口的子类(即CursorLoader
,在这种情况下)。这个CursorLoader
将执行初始查询,并在数据更改时自行更新。
如果您的活动/片段有多个加载器,那么您将使用switch(id)
来确定已指示开始加载过程的特定加载器。
查询到的游标传给onLoadFinished()
。
CursorLoader
在步骤 3 中被实例化并返回后,CursorLoader
立即在单独的线程上执行初始查询并返回游标。当CursorLoader
完成查询时,它将新查询的游标返回给LoaderManager
,然后将游标传递给onLoadFinished
方法。在文档中,“onLoadFinished
方法在先前创建的加载程序完成加载时被调用。”
查询到的数据与CursorAdapter
相关联。
mAdapter.swapCursor(data);
请注意,onLoadFinished
通常也是您使用查询数据更新活动/片段的 UI 的地方。在这种情况下这不是必需的,因为我们之前称之为setListAdapter(mAdapter)
。 ListFragment
知道如何使用 CursorAdapter
(参见步骤 1)......我们需要做的就是将光标传递给适配器 swapCursor
,ListFragment
将负责在我们的屏幕。
如果您有任何问题(或者是否有任何拼写错误等),请告诉我。
TL;DR
包含查询数据的游标与CursorAdapter
中的onLoadFinished
相关联。这通常通过调用mAdapter.swapCursor(data)
来完成。
【讨论】:
在装载机上的出色运行 不要感谢我...感谢 Android 市场上所有糟糕的、开发不佳的应用程序。这就是我觉得有责任过度详细解释这个过程的原因。 :) 嘿@AlexLockwood 快速提问。如果我将 CursorLoader 与 LoaderManager 一起使用,我无需担心关闭数据库或游标是否正确。但是当我像getContentResolver().query()
一样直接使用它时呢?在这种情况下,我是否必须明确关闭它们,或者所有这些仍然由类本身处理?
然后,在这些方法中,CursorLoader
将相应地关闭其游标(即在onReset
等中)。换句话说,不是LoaderManager
关闭游标……而是LoaderManager
告诉CursorLoader
关闭游标。
@IgorGanapolsky 我记得和其他一些 Android 开发者讨论过这个问题here。我总是在onActivityCreated()
中初始化加载器。我同意你的观点,谷歌的文档对这一点有点含糊……但我在 onActivityCreated()
中初始化加载器时从未遇到任何问题。以上是关于带 LoaderManager 的 CursorLoader 如何知道将光标发送到 CursorAdapter?的主要内容,如果未能解决你的问题,请参考以下文章