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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 06:09:34  来源:igfitidea点击:

How does CursorLoader with LoaderManager know to send the cursor to a CursorAdapter?

androidandroid-contentproviderandroid-loadermanagerandroid-cursorloader

提问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.

我正在浏览我的一些代码,我意识到我实际上并不知道如何将 aCursorLoaderLoaderManager组合与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(在此问题的上下文中,差异并不重要)。



  1. 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's Contacts.DISPLAY_NAMEcolumn will be associated with the view with id android.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 the LoaderManagerand CursorLoader's job).

  2. Next, initialize the loader.

    getLoaderManager().initLoader(0, null, this);
    

    This tells the LoaderManagerto create and start the Loadercorresponding to id 0.

  3. The LoaderManagercalls onCreateLoader(int id, Bundle args).

    onCreateloaderreturns a subclass of the Loader<Cursor>interface (i.e. a CursorLoader, in this case). This CursorLoaderwill 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.

  4. The queried cursor is passed to onLoadFinished().

    Immediately after the CursorLoaderis instantiated and returned in step 3, the CursorLoaderperforms the initial query on a separate thread and a cursor is returned. When the CursorLoaderfinishes the query, it returns the newly queried cursor to the LoaderManager, which then passes the cursor to the onLoadFinishedmethod. From the documentation, "the onLoadFinishedmethod is called when a previously created loader has finished its load."

  5. 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 called setListAdapter(mAdapter). The ListFragmentknows how to use the CursorAdapter(see step 1)... all we need to do is pass the adapter the cursor with swapCursor, and the ListFragmentwill take care of displaying the data on the screen for us.

  1. 首先,创建(并设置)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的工作)。

  2. 接下来,初始化加载器。

    getLoaderManager().initLoader(0, null, this);
    

    这告诉LoaderManager创建并启动Loader对应的 id 0

  3. LoaderManager电话onCreateLoader(int id, Bundle args)

    onCreateloader返回Loader<Cursor>接口的子类(即 a CursorLoader,在这种情况下)。这CursorLoader将执行初始查询,并在数据更改时自行更新。

    如果您的 Activity/Fragment 有多个加载器,那么您将用于switch(id)确定已被指示开始加载过程的特定加载器。

  4. 查询的游标被传递给onLoadFinished()

    CursorLoader在第 3 步中实例化并返回之后, 立即在CursorLoader单独的线程上执行初始查询并返回一个游标。当CursorLoader完成查询时,它将新查询的游标返回给LoaderManager,然后将游标传递给onLoadFinished方法。从文档中,“onLoadFinished当先前创建的加载器完成加载时调用该方法。”

  5. 查询的数据与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).