带有LoaderManager的CursorLoader如何知道将光标发送到CursorAdapter?

And*_*ndy 22 android android-contentprovider android-loadermanager android-cursorloader

我正在浏览一些代码,我意识到我实际上并不知道如何使用连接CursorLoaderLoaderManager组合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);
Run Code Online (Sandbox Code Playgroud)

那么query()我的自定义方法如何ContentProvider将其发送到特定的方法CursorAdapter呢?我只是没有看到连接.我理解其他一切,但这个问题是什么.哦,我应该提一下,代码工作正常.

Ale*_*ood 84

首先,请查看本文本文中的代码示例,以便更深入地了解该过程的工作原理.

现在,回答你的问题......

query()方法是如何从我的自定义ContentProvider...?

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

如何将查询发送到该特定的CursorAdapter

我将以API演示为例,引导您完成整个过程.请注意,API演示使用的是a ListFragment而不是a ListActivity(差异在此问题的上下文中并不重要).


  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);
    
    Run Code Online (Sandbox Code Playgroud)

    执行此语句后,它SimpleCursorAdapter知道如何将游标数据与您的视图相关联.光标Contacts.DISPLAY_NAME列中的任何数据都将与具有id android.R.id.text1等的视图相关联.

    请注意,您已将null游标作为构造函数的第三个参数传递.这非常重要,因为我们还没有查询任何数据(这是LoaderManagerCursorLoader工作).

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

    getLoaderManager().initLoader(0, null, this);
    
    Run Code Online (Sandbox Code Playgroud)

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

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

    onCreateloader返回Loader<Cursor>接口的子类(CursorLoader在本例中为a).这CursorLoader将执行初始查询,并在数据更改时自行更新.

    如果您的活动/片段有多个加载器,那么您将用于switch(id)确定已指示开始加载过程的特定加载器.

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

    CursorLoader实例化并在步骤3中返回之后,立即在CursorLoader单独的线程上执行初始查询并返回游标.当CursorLoader结束该查询时,它返回新查询光标移动到LoaderManager,这随后将光标移动到onLoadFinished方法.从文档中,"在onLoadFinished先前创建的加载器完成其加载时调用该方法."

  5. 查询的数据与CursorAdapter.

    mAdapter.swapCursor(data);
    
    Run Code Online (Sandbox Code Playgroud)

    请注意,onLoadFinished通常也会使用查询的数据更新活动/片段的UI.在这种情况下,这不是必要的,正如我们之前所说的那样setListAdapter(mAdapter).该ListFragment知道如何使用CursorAdapter(见步骤1)......我们需要做的是通过适配器的光标swapCursor,而ListFragment将采取的屏幕为我们上显示数据的照顾.

如果您有任何疑问(或者有任何拼写错误等),请告诉我.


TL; DR

包含查询数据的游标与CursorAdapterin 关联onLoadFinished.这通常通过调用来完成mAdapter.swapCursor(data).

  • 不要感谢我...感谢Android市场上所有糟糕的,开发不佳的应用程序.他们之所以有责任以**过多的细节来解释这个过程.:) (13认同)
  • 很棒的装载机 (2认同)
  • 然后,在这些方法中,`CursorLoader`将相应地关闭其游标(即在[**`onReset`**](http://bit.ly/M3eFqJ)等).换句话说,它不是关闭游标的`LoaderManager` ......它是`LoaderManager`告诉'CursorLoader`关闭游标. (2认同)