Android 带有 LoaderManager 的 CursorLoader 如何知道将游标发送到 CursorAdapter?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11150527/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does CursorLoader with LoaderManager know to send the cursor to a CursorAdapter?
提问by Andy
I was going through some of my code and I realized I don't actually know how a CursorLoaderand LoaderManagercombination used with a CursorAdapterconnect. Heres the part that I am confused in.
我正在浏览我的一些代码,我意识到我实际上并不知道如何将 aCursorLoader和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);
So how does the query()method from my custom ContentProviderknow to send it to that specific CursorAdapter? I just don't see the connection. I understand everything else in that but what this question is on. Oh and I should mention, the code works fine.
那么query()我的自定义方法如何ContentProvider知道将它发送到特定的CursorAdapter?我只是看不到联系。我理解其中的所有其他内容,但这个问题是关于什么的。哦,我应该提到,代码工作正常。
回答by Alex Lockwood
First of all, check out the code sample at this postand this postfor an even more in-depth look into how the process works.
首先,查看这篇文章和这篇文章中的代码示例,以更深入地了解该过程的工作原理。
And now, to answer your questions...
现在,回答你的问题......
How does the query() method from my custom
ContentProvider...?
我的自定义中的 query() 方法如何
ContentProvider......?
Well, first remember that getContentResolver().query()doesn't invoke the content provider's querymethod directly. You are invoking the content resolver's query method, which parses the Uri, determines the provider you wish to invoke, and thencalls your provider's querymethod.
好吧,首先记住这getContentResolver().query()不会直接调用内容提供者的query方法。您正在调用内容解析器的查询方法,该方法解析Uri,确定您希望调用的提供程序,然后调用您的提供程序的query方法。
How does the query get sent to that specific
CursorAdapter?
查询如何发送到特定的
CursorAdapter?
I'll walk you through the process using the API Demosas an example. Note that the API demos uses a ListFragmentinstead of a ListActivity(the difference is not important in the context of this question).
我将使用API 演示作为示例引导您完成整个过程。请注意,API 演示使用 aListFragment而不是 a ListActivity(在此问题的上下文中,差异并不重要)。
First, create (and set up) the
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);After this statement is executed, the
SimpleCursorAdapterknows how it should associate the cursor data with your views. Whatever data is in the cursor'sContacts.DISPLAY_NAMEcolumn will be associated with the view with idandroid.R.id.text1, etc.Note that you have passed a
nullcursor as the third argument to the constructor. This is very important, as we have not queried any data yet (this is theLoaderManagerandCursorLoader's job).Next, initialize the loader.
getLoaderManager().initLoader(0, null, this);This tells the
LoaderManagerto create and start theLoadercorresponding to id0.The
LoaderManagercallsonCreateLoader(int id, Bundle args).onCreateloaderreturns a subclass of theLoader<Cursor>interface (i.e. aCursorLoader, in this case). ThisCursorLoaderwill perform the initial query and will update itself when the data changes.If your activity/fragment has more than one loader, then you'd use
switch(id)to determine the specific loader that has been instructed to begin the loading process.The queried cursor is passed to
onLoadFinished().Immediately after the
CursorLoaderis instantiated and returned in step 3, theCursorLoaderperforms the initial query on a separate thread and a cursor is returned. When theCursorLoaderfinishes the query, it returns the newly queried cursor to theLoaderManager, which then passes the cursor to theonLoadFinishedmethod. From the documentation, "theonLoadFinishedmethod is called when a previously created loader has finished its load."The queried data is associated with the
CursorAdapter.mAdapter.swapCursor(data);Note that
onLoadFinishedis also typically where you update the activity/fragment's UI with the queried data. This isn't necessary in this case, as we have previously calledsetListAdapter(mAdapter). TheListFragmentknows how to use theCursorAdapter(see step 1)... all we need to do is pass the adapter the cursor withswapCursor, and theListFragmentwill take care of displaying the data on the screen for us.
首先,创建(并设置)
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列中的任何数据都将与带有 idandroid.R.id.text1等的视图相关联。请注意,您已将
null游标作为第三个参数传递给构造函数。这非常重要,因为我们还没有查询任何数据(这是LoaderManagerandCursorLoader的工作)。接下来,初始化加载器。
getLoaderManager().initLoader(0, null, this);这告诉
LoaderManager创建并启动Loader对应的 id0。该
LoaderManager电话onCreateLoader(int id, Bundle args)。onCreateloader返回Loader<Cursor>接口的子类(即 aCursorLoader,在这种情况下)。这CursorLoader将执行初始查询,并在数据更改时自行更新。如果您的 Activity/Fragment 有多个加载器,那么您将用于
switch(id)确定已被指示开始加载过程的特定加载器。查询的游标被传递给
onLoadFinished()。CursorLoader在第 3 步中实例化并返回之后, 立即在CursorLoader单独的线程上执行初始查询并返回一个游标。当CursorLoader完成查询时,它将新查询的游标返回给LoaderManager,然后将游标传递给onLoadFinished方法。从文档中,“onLoadFinished当先前创建的加载器完成加载时调用该方法。”查询的数据与
CursorAdapter.mAdapter.swapCursor(data);请注意,这
onLoadFinished通常也是您使用查询数据更新活动/片段 UI 的地方。在这种情况下,这不是必需的,正如我们之前所说的setListAdapter(mAdapter)。该ListFragment知道如何使用CursorAdapter(见步骤1)......我们需要做的是通过适配器的光标swapCursor,而ListFragment将采取的屏幕为我们上显示数据的照顾。
Let me know if you have any questions (or if there are any typos, etc.).
如果您有任何问题(或者是否有拼写错误等),请告诉我。
TL;DR
TL; 博士
The cursor that contains your queried data is associated with the CursorAdapterin onLoadFinished. This is typically done by calling mAdapter.swapCursor(data).
包含查询数据的游标与CursorAdapterin相关联onLoadFinished。这通常通过调用mAdapter.swapCursor(data).

