Android官方开发文档Training系列课程中文版:后台加载数据之使用CursorLoader进行查询

来源:互联网 发布:用php写一个 编辑:程序博客网 时间:2024/05/21 11:09

原文地址:http://android.xsoftlab.net/training/load-data-background/index.html

引言

在ContentProvider中查询数据是需要花点时间的。如果你直接在Activity进行查询,那么这可能会导致UI线程阻塞,并会引起”Application Not Responding”异常。就算不会发生这些事情,那么用户也能感觉到卡顿,这会非常恼人的。为了避免这样的问题,应该将查询的工作放在单独的线程中执行,然后等待它执行完毕后将结果显示出来。

你可以使用一个异步查询对象在后台查询,然后等查询结束之后再与Activity建立连接。这个对象就是我们要说的CursorLoader。CursorLoader除了可以进行基本查询之外,还可以在数据发生变化后自动的重新进行查询。

这节课主要会学习如何使用CursorLoader在后台进行查询。

使用CursorLoader进行查询

CursorLoader对象在后台运行着一个异步查询,当查询结束之后会将结果返回到Activity或FragmentActivity。这使得查询在进行的过程中Activity或FragmentActivity还可以继续与用户交互。

定义使用CursorLoader的Activity

如果要在Activity中使用CursorLoader,需要用到LoaderCallbacks接口。CursorLoader会调用该接口中的方法,从而使得与Activity产生交互。这节课与下节课都会详细描述该接口中的回调。

举个例子,下面的代码演示了如何定义一个使用了CursorLoader的FragmentActivity。通过继承FragmentActivity,你可以获得CursorLoader对Fragment的支持:

public class PhotoThumbnailFragment extends FragmentActivity implements        LoaderManager.LoaderCallbacks<Cursor> {...}

初始化查询

使用LoaderManager.initLoader()可以初始化查询。它其实初始化了后台查询框架。可以将初始化这部分工作放在用户输入了需要查询的数据之后,或者如果不需要用户输入数据,那么也可以将这部分工作放在onCreate()或onCreateView()中执行:

    // Identifies a particular Loader being used in this component    private static final int URL_LOADER = 0;    ...    /* When the system is ready for the Fragment to appear, this displays     * the Fragment's View     */    public View onCreateView(            LayoutInflater inflater,            ViewGroup viewGroup,            Bundle bundle) {        ...        /*         * Initializes the CursorLoader. The URL_LOADER value is eventually passed         * to onCreateLoader().         */        getLoaderManager().initLoader(URL_LOADER, null, this);        ...    }

Note: getLoaderManager()方法只对Fragment类可用。如果需要在FragmentActivity中获得LoaderManager,调用getSupportLoaderManager()方法即可。

开始查询

后台查询框架的初始化一旦完成,紧接着你所实现的onCreateLoader()就会被调用。如果要启动查询,需要在该方法内返回一个CursorLoader对象。你可以实例化一个空的CursorLoader,然后再使用它的方法定义查询,或者你也可以在实例化CursorLoader的时候定义查询。

/** Callback that's invoked when the system has initialized the Loader and* is ready to start the query. This usually happens when initLoader() is* called. The loaderID argument contains the ID value passed to the* initLoader() call.*/@Overridepublic Loader<Cursor> onCreateLoader(int loaderID, Bundle bundle){    /*     * Takes action based on the ID of the Loader that's being created     */    switch (loaderID) {        case URL_LOADER:            // Returns a new CursorLoader            return new CursorLoader(                        getActivity(),   // Parent activity context                        mDataUrl,        // Table to query                        mProjection,     // Projection to return                        null,            // No selection clause                        null,            // No selection arguments                        null             // Default sort order        );        default:            // An invalid id was passed in            return null;    }}

一旦后台查询框架获得了该对象,那么它会马上在后台开始查询。当查询结果完成,后台查询框架会调用onLoadFinished(),该方法的具体内容会在下节课说明。

1 0
原创粉丝点击