关于android:CursorLoader 和LoaderManager 是如何知道将光标发送到CursorAdapter 的?

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

我正在浏览我的一些代码,我意识到我实际上并不知道 CursorLoaderLoaderManager 组合如何与 CursorAdapter 连接一起使用。这是我感到困惑的部分。

1
2
3
4
5
6
7
8
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?我只是没有看到联系。我了解其中的所有其他内容,但这个问题是关于什么的。哦,我应该提一下,代码运行良好。


首先,查看这篇文章和这篇文章中的代码示例,以更深入地了解该过程的工作原理。

现在,回答你的问题……

How does the query() method from my custom ContentProvider...?

嗯,首先要记住 getContentResolver().query() 不会直接调用内容提供者的 query 方法。您正在调用内容解析器的查询方法,该方法解析 Uri,确定您希望调用的提供程序,然后调用您的提供程序的 query 方法。

How does the query get sent to that specific CursorAdapter?

我将使用 API 演示作为示例来引导您完成整个过程。请注意,API 演示使用 ListFragment 而不是 ListActivity (区别在这个问题的上下文中并不重要)。

  • 首先,创建(并设置)CursorAdapter.

    1
    2
    3
    4
    5
    6
    7
    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 游标作为第三个参数传递给构造函数。这非常重要,因为我们还没有查询任何数据(这是 LoaderManagerCursorLoader 的工作)。

  • 接下来,初始化加载器。

    1
    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相关联。

    1
    mAdapter.swapCursor(data);

    请注意,onLoadFinished 通常也是您使用查询数据更新活动/片段的 UI 的地方。在这种情况下,这不是必需的,因为我们之前称为 setListAdapter(mAdapter)ListFragment 知道如何使用 CursorAdapter(参见步骤 1)...我们需要做的就是将光标与 swapCursor 一起传递给适配器,而 ListFragment 将负责在我们的屏幕。

  • 如果您有任何问题(或者是否有任何拼写错误等),请告诉我。

    TL;博士

    包含查询数据的游标与onLoadFinished中的CursorAdapter相关联。这通常通过调用 mAdapter.swapCursor(data).

    来完成