【翻译】(5)加载器

【翻译】(5)加载器

 

see

http://developer.android.com/guide/topics/fundamentals/loaders.html

 

原文见

http://developer.android.com/guide/topics/fundamentals/loaders.html

 

-------------------------------

 

Loaders

 

加载器

 

-------------------------------

 

In this document

 

本文目录

 

* Loader API Summary 加载器摘要

* Using Loaders in an Application 在应用程序中使用加载器

* Starting a Loader 启动加载器

* Restarting a Loader 重启加载器

* Using the LoaderManager Callbacks 使用LoaderManager回调

* Example 示例

* More Examples 更多示例

 

Key classes

 

关键类

 

* LoaderManager

* Loader

 

Related samples

 

相关示例

 

LoaderCursor

LoaderThrottle

 

-------------------------------

 

Introduced in Android 3.0, loaders make it easy to asynchronously load data in an activity or fragment. Loaders have these characteristics:

 

在Android 3.0内引入,加载器使在活动或片段内异步加载数据变得容易。加载器有这些特性:

 

* They are available to every Activity and Fragment.

 

* 它们对于每个活动和片段是可用的。

 

* They provide asynchronous loading of data.

 

* 它们提供数据的异步加载。

 

* They monitor the source of their data and deliver new results when the content changes.

 

* 它们监视它们的数据源并且在内容改变时派发新的结果。

 

* They automatically reconnect to the last loader's cursor when being recreated after a configuration change. Thus, they don't need to re-query their data.

 

* 当在配置改变后它们正在重建时,它们会自动重连至最后的加载器游标。这么一来,它们就不需要重新查询它们的数据。

 

-------------------------------

 

Loader API Summary

 

加载器API摘要

 

There are multiple classes and interfaces that may be involved in using loaders in an application. They are summarized in this table:

 

在应用程序中使用加载器可能会涉及多个类和接口。它们总结在这个表格中:

 

-------------------------------

 

Class/Interface Description

 

类/接口 描述

 

* LoaderManager An abstract class associated with an Activity or Fragment for managing one or more Loader instances. This helps an application manage longer-running operations in conjunction with the Activity or Fragment lifecycle; the most common use of this is with a CursorLoader, however applications are free to write their own loaders for loading other types of data. 

 

* LoaderManager:一个抽象类,与活动或片段关联,用于管理一个或多个加载器实例。它帮助应用程序管理长期运行的操作,与活动或片段的生命周期相结合;它最常见的用法是使用CursorLoader,然而应用程序可以自由书写它们自己的加载器用于加载其它类型的数据。

 

There is only one LoaderManager per activity or fragment. But a LoaderManager can have multiple loaders.

 

每个活动或片段只有一个LoaderManager。但一个LoaderManager可以拥有多个加载器。

 

* LoaderManager.LoaderCallbacks A callback interface for a client to interact with the LoaderManager. For example, you use the onCreateLoader() callback method to create a new loader.

 

* LoaderManager.LoaderCallbacks:回调接口,用于客户端与LoaderManager的交互。例如,你使用onCreateLoader()回调方法创建新的加载器。

 

* Loader An abstract class that performs asynchronous loading of data. This is the base class for a loader. You would typically use CursorLoader, but you can implement your own subclass. While loaders are active they should monitor the source of their data and deliver new results when the contents change.

 

* 加载器:一个抽象类,执行数据的异步加载。它是加载器的基类。你通常使用CursorLoader,但你可以实现你自己的子类。当加载器被激活时,它们应该会监视它们的数据源并且当内容改变时派发新的结果。

 

* AsyncTaskLoader Abstract loader that provides an AsyncTask to do the work.

 

* AsyncTaskLoader:抽象加载器,提供一个AsyncTask完成工作。

 

* CursorLoader A subclass of AsyncTaskLoader that queries the ContentResolver and returns a Cursor. This class implements the Loader protocol in a standard way for querying cursors, building on AsyncTaskLoader to perform the cursor query on a background thread so that it does not block the application's UI. Using this loader is the best way to asynchronously load data from a ContentProvider, instead of performing a managed query through the fragment or activity's APIs.

 

* CursorLoader:AsyncTaskLoader的子类,查询ContentResolver并且返回一个Cursor对象。此类以查询游标的标准形式实现Loader协议,在AsyncTaskLoader上构建,在后台线程中执行游标查询以致它不会阻塞应用程序的用户界面。使用此加载器是异步从ContentProvider加载数据的最佳方法,代替通过片段或活动API执行的托管查询。

 

-------------------------------

 

The classes and interfaces in the above table are the essential components you'll use to implement a loader in your application. You won't need all of them for each loader you create, but you'll always need a reference to the LoaderManager in order to initialize a loader and an implementation of a Loader class such as CursorLoader. The following sections show you how to use these classes and interfaces in an application.

 

上表中的类和接口是你将用于在你的应用程序中实现加载器的本质组件。对于你创建的每个加载器,你将不需要它们的全部,但你将总是需要一个指向LoaderManager的引用,以便初始化一个加载器和一个加载器类的实现诸如CursorLoader。以下章节向你展示如何在应用程序中使用这些类和接口。

 

-------------------------------

 

Using Loaders in an Application

 

在应用程序中使用加载器

 

This section describes how to use loaders in an Android application. An application that uses loaders typically includes the following:

 

此章节描述如何在一个Android应用程序中使用加载器。一个使用加载器的应用程序通常包括以下内容:

 

* An Activity or Fragment.

 

* 一个活动或片段。

 

* An instance of the LoaderManager.

 

* 一个LoaderManager实例。

 

* A CursorLoader to load data backed by a ContentProvider. Alternatively, you can implement your own subclass of Loader or AsyncTaskLoader to load data from some other source.

 

* 一个用于加载由ContentProvider提供的数据的CursorLoader。可选地,你可以实现你自己的Loader或AsyncTaskLoader的子类,以加载来自其它源的数据。

 

* An implementation for LoaderManager.LoaderCallbacks. This is where you create new loaders and manage your references to existing loaders.

 

LoaderManager.LoaderCallbacks的实现。在这个回调中你创建新的加载器并管理你的现存加载器的引用。

 

* A way of displaying the loader's data, such as a SimpleCursorAdapter.

 

* 一个显示加载器数据的方式,诸如一个SimpleCursorAdapter

 

* A data source, such as a ContentProvider, when using a CursorLoader.

 

* 一个数据源,诸如ContentProvider,当使用CursorLoader时。

 

Starting a Loader

 

启动加载器

 

The LoaderManager manages one or more Loader instances within an Activity or Fragment. There is only one LoaderManager per activity or fragment.

 

在活动或片段中,LoaderManager管理一个或多个加载器实例。每个活动或片段只有一个LoaderManager。

 

You typically initialize a Loader within the activity's onCreate() method, or within the fragment's onActivityCreated() method. You do this as follows:

 

你通常在活动的onCreate()内,或在片段的onActivityCreated()方法内初始化一个Loader。你可以像如下所示做到这一点:

 

-------------------------------

 

// Prepare the loader.  Either re-connect with an existing one,

// or start a new one.

// 准备加载器。要么用现存加载器重连,要么启动新的加载器。

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

 

-------------------------------

 

The initLoader() method takes the following parameters:

 

initLoader()方法传入以下参数:

 

* A unique ID that identifies the loader. In this example, the ID is 0.

 

* 一个标识加载器的唯一ID。在这个示例中,ID是0.

 

* Optional arguments to supply to the loader at construction (null in this example).

 

* 在构造函数中提供给加载器的可选参数(此示例中为null)

 

* A LoaderManager.LoaderCallbacks implementation, which the LoaderManager calls to report loader events. In this example, the local class implements the LoaderManager.LoaderCallbacks interface, so it passes a reference to itself, this.

 

* 一个LoaderManager.LoaderCallbacks实现,它被LoaderManager调用来报告加载器事件。在此示例中,内部类实现LoaderManager.LoaderCallbacks接口,所以它传递指向它自己的引用this。

 

The initLoader() call ensures that a loader is initialized and active. It has two possible outcomes:

 

initLoader()的调用确保加载器被初始化并激活。它有两个可能的结果:

 

* If the loader specified by the ID already exists, the last created loader is reused.

 

* 如果加载器由现存的ID指定,最后创建的加载器会被重用。

 

* If the loader specified by the ID does not exist, initLoader() triggers the LoaderManager.LoaderCallbacks method onCreateLoader(). This is where you implement the code to instantiate and return a new loader. For more discussion, see the section onCreateLoader.

 

* 如果加载器由不存在的ID指定,那么initLoader()触发LoaderManager.LoaderCallbacks的方法onCreateLoader()。在此方法中你的实现代码初始化并返回新的加载器。更多讨论,请参看onCreateLoader章节。

 

In either case, the given LoaderManager.LoaderCallbacks implementation is associated with the loader, and will be called when the loader state changes. If at the point of this call the caller is in its started state, and the requested loader already exists and has generated its data, then the system calls onLoadFinished() immediately (during initLoader()), so you must be prepared for this to happen. See onLoadFinished for more discussion of this callback

 

不管是两种情况中的哪一种,指定的LoaderManager.LoaderCallbacks实现被关联到加载器,并在加载器状态改变时被调用。如果在此调用的发生点上调用者正处于它的被启动状态,并且请求的加载器已经存在,以及已经生成它的数据,那么系统立刻调用onLoadFinished()(在initLoader()期间),所以你必须准备它要发生。参看onLoadFinished以获取关于此回调的更多讨论。

 

Note that the initLoader() method returns the Loader that is created, but you don't need to capture a reference to it. The LoaderManager manages the life of the loader automatically. The LoaderManager starts and stops loading when necessary, and maintains the state of the loader and its associated content. As this implies, you rarely interact with loaders directly (though for an example of using loader methods to fine-tune a loader's behavior, see the LoaderThrottle sample). You most commonly use the LoaderManager.LoaderCallbacks methods to intervene in the loading process when particular events occur. For more discussion of this topic, see Using the LoaderManager Callbacks.

 

注意initLoader()方法返回被创建的加载器,但你不需要捕捉它的引用。LoaderManager自动管理加载器的生命。在需要时LoaderManager启动和停止加载,并维护加载器的状态以及它所关联的内容。正如它所暗示的,你很少直接与加载器交互(但对于使用加载器方法以微调加载器的行为的示例则不然,请参考LoaderThrottle示例)。最常见的是,当特殊的事件发生时,你使用LoaderManager.LoaderCallbacks方法干预加载的过程。关于此问题的更多讨论,请参考LoaderManager回调的使用。

 

Restarting a Loader

 

重启加载器

 

When you use initLoader(), as shown above, it uses an existing loader with the specified ID if there is one. If there isn't, it creates one. But sometimes you want to discard your old data and start over.

 

当你使用initLoader(),正如上面演示的那样,它使用一个带指定ID的现存加载器,如果有的话。如果没有,它会创建一个ID。但有时你需要丢弃你的旧数据并重新开始。

 

To discard your old data, you use restartLoader(). For example, this implementation of SearchView.OnQueryTextListener restarts the loader when the user's query changes. The loader needs to be restarted so that it can use the revised search filter to do a new query:

 

为了丢弃你的旧数据,你使用restartLoader()。例如,这个SearchView.OnQueryTextListener实现当用户查询改变时重启加载器。加载器需要重启以致使它可以使用被修改的搜索过滤器以完成新的查询:

 

-------------------------------

 

public boolean onQueryTextChanged(String newText) {

    // Called when the action bar search text has changed.  Update

    // the search filter, and restart the loader to do a new query

    // with this filter.

// 当动作栏搜索文本被修改时调用。

// 更新搜索过滤器,并重启加载器以用此过滤器完成新的查询。

    mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;

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

    return true;

}

 

-------------------------------

 

Using the LoaderManager Callbacks

 

使用LoaderManager回调

 

LoaderManager.LoaderCallbacks is a callback interface that lets a client interact with the LoaderManager.

 

LoaderManager.LoaderCallbacks是一个回调接口,让一个客户端与LoaderManager交互。

 

Loaders, in particular CursorLoader, are expected to retain their data after being stopped. This allows applications to keep their data across the activity or fragment's onStop() and onStart() methods, so that when users return to an application, they don't have to wait for the data to reload. You use the LoaderManager.LoaderCallbacks methods when to know when to create a new loader, and to tell the application when it is time to stop using a loader's data.

 

加载器,尤其是CursorLoader,期待在它被停止之后保持其数据。允许应用程序跨活动或片段的onStop()和onStart()方法保持其数据,以致当用户返回到应用程序时,他们不必等待数据重新加载。当你想知道何时创建一个新加载器时,你会使用LoaderManager.LoaderCallbacks方法,它会在停止使用加载器数据的时候立刻告诉应用程序。

 

LoaderManager.LoaderCallbacks includes these methods:

 

LoaderManager.LoaderCallbacks包含这些方法:

 

* onCreateLoader() — Instantiate and return a new Loader for the given ID.

 

* onCreateLoader()——初始化并返回给定ID的新加载器

 

* onLoadFinished() — Called when a previously created loader has finished its load.

 

* onLoadFinished()——当之前被创建的加载器已经完成其加载时被调用。

 

* onLoaderReset() — Called when a previously created loader is being reset, thus making its data unavailable.

 

* onLoaderReset()——当之前创建的加载器被重置时被创建,它使其数据不可用。

 

These methods are described in more detail in the following sections.

 

在下面的章节中会详细描述这些方法。

 

onCreateLoader

 

When you attempt to access a loader (for example, through initLoader()), it checks to see whether the loader specified by the ID exists. If it doesn't, it triggers the LoaderManager.LoaderCallbacks method onCreateLoader(). This is where you create a new loader. Typically this will be a CursorLoader, but you can implement your own Loader subclass.

 

当你尝试访问一个加载器(例如,通过initLoader()),它检查ID指定的加载器是否存在。如果不存在,它触发LoaderManager.LoaderCallbacks方法onCreateLoader()。在这个方法里你创建新的加载器。通常它是一个CursorLoader,但你可以实现你自己的Loader子类。

 

In this example, the onCreateLoader() callback method creates a CursorLoader. You must build the CursorLoader using its constructor method, which requires the complete set of information needed to perform a query to the ContentProvider. Specifically, it needs:

 

在这个示例中,onCreateLoader()回调方法创建一个CursorLoader,你必须使用其构造函数构建CursorLoader对象,该构造函数需要完整的信息集合,需要用其执行对ContentProvider的查询。典型地,它需要:

 

* uri — The URI for the content to retrieve.

 

* uri——获取内容的URI。

 

* projection — A list of which columns to return. Passing null will return all columns, which is inefficient.

 

* projection——返回列的列表。传递null将返回所有列,这样效率较低。

 

* selection — A filter declaring which rows to return, formatted as an SQL WHERE clause (excluding the WHERE itself). Passing null will return all rows for the given URI.

 

* selection——一个过滤器声明返回的行,被格式化作为SQL WHERE分句(不包含WHERE自身)。传递null将返回所给URI的所有行。

 

* selectionArgs — You may include ?s in the selection, which will be replaced by the values from selectionArgs, in the order that they appear in the selection. The values will be bound as Strings.

 

* selectionArgs——你可能放进selection中的嵌入物,它将被selectionArgs的值替换,根据它们在selection中出现的顺序。这些值将被限制作为String。

 

* sortOrder — How to order the rows, formatted as an SQL ORDER BY clause (excluding the ORDER BY itself). Passing null will use the default sort order, which may be unordered.

 

* sortOrder——如何排序行,被格式化作为SQL ORDER BY分句(不包括ORDER BY自身)。传递null将使用默认的排序顺序,可能是未排序的。

 

For example:

 

例如:

 

-------------------------------

 

 // If non-null, this is the current filter the user has provided.

 // 如果非空,它是用户提供过的当前过滤器

String mCurFilter;

...

public Loader<Cursor> onCreateLoader(int id, Bundle args) {

    // This is called when a new Loader needs to be created.  This

    // sample only has one Loader, so we don't care about the ID.

    // First, pick the base URI to use depending on whether we are

    // currently filtering.

// 当新加载器需要被创建时,这个方法被调用。这个示例只有一个加载器,

// 所以我们不关心ID。首先,根据我们是否正在被过滤,获取要使用的基本URI。

    Uri baseUri;

    if (mCurFilter != null) {

        baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,

                  Uri.encode(mCurFilter));

    } else {

        baseUri = Contacts.CONTENT_URI;

    }

 

    // Now create and return a CursorLoader that will take care of

    // creating a Cursor for the data being displayed.

    // 现在创建和返回CursorLoader对象,它将负责创建用于要显示数据的游标。

    String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND ("

            + Contacts.HAS_PHONE_NUMBER + "=1) AND ("

            + Contacts.DISPLAY_NAME + " != '' ))";

    return new CursorLoader(getActivity(), baseUri,

            CONTACTS_SUMMARY_PROJECTION, select, null,

            Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");

}

 

-------------------------------

 

onLoadFinished

 

This method is called when a previously created loader has finished its load. This method is guaranteed to be called prior to the release of the last data that was supplied for this loader. At this point you should remove all use of the old data (since it will be released soon), but should not do your own release of the data since its loader owns it and will take care of that.

 

当之前创建的加载器已经完成其加载时,此方法被调用。此方法保证在提供给加载器的最后数据释放之前被调用。在这个时间点上你应该移除所有对旧数据的使用(因为它将在不久后被释放),但不应该进行你自己的数据释放,因为它的加载器拥有它并将负责完成这些工作。

 

The loader will release the data once it knows the application is no longer using it. For example, if the data is a cursor from a CursorLoader, you should not call close() on it yourself. If the cursor is being placed in a CursorAdapter, you should use the swapCursor() method so that the old Cursor is not closed. For example:

 

加载器将释放数据,一旦它知道应用程序不再使用。例如,如果数据是一个来自CursorLoader的游标,那么你不应该自己对它调用close()。如果游标被放置进CursorAdapter,你应该使用swapCursor()方法,以致使旧的游标不被关闭。例如:

 

-------------------------------

 

// This is the Adapter being used to display the list's data.

// 这是用于显示列表数据的适配器。

SimpleCursorAdapter mAdapter;

...

 

public void onLoadFinished(Loader<Cursor> loader, Cursor data) {

    // Swap the new cursor in.  (The framework will take care of closing the

    // old cursor once we return.)

    // 交换进新的游标。(一旦我们返回,框架将负责关闭旧游标)

    mAdapter.swapCursor(data);

}

 

-------------------------------

 

onLoaderReset

 

This method is called when a previously created loader is being reset, thus making its data unavailable. This callback lets you find out when the data is about to be released so you can remove your reference to it.  

 

当之前被创建的加载器被重置时,此方法被调用,这致使其数据不可用。此回调让你找出数据将在何时被释放,使你可以移除你对它的引用。

 

This implementation calls swapCursor() with a value of null:

 

这里的实现用null值调用swapCursor()。

 

-------------------------------

 

// This is the Adapter being used to display the list's data.

// 这是用于显示列表数据的适配器。

SimpleCursorAdapter mAdapter;

...

 

public void onLoaderReset(Loader<Cursor> loader) {

    // This is called when the last Cursor provided to onLoadFinished()

    // above is about to be closed.  We need to make sure we are no

    // longer using it.

    // 当上面提供给onLoadFinished()的最后Cursor将被关闭时,此方法被调用。

    // 我们需要确保我们不再使用它。

    mAdapter.swapCursor(null);

}

 

-------------------------------

 

Example

 

示例

 

As an example, here is the full implementation of a Fragment that displays a ListView containing the results of a query against the contacts content provider. It uses a CursorLoader to manage the query on the provider.

 

作为例子,这里是片段的完整实现,显示一个ListView,包含对电话簿内容提供者的查询结果。它使用CursorLoader管理对提供者的查询。

 

For an application to access a user's contacts, as shown in this example, its manifest must include the permission READ_CONTACTS.

 

为了让应用程序访问用户的电话簿,正如此示例所示,它的清单必须包含READ_CONTACTS权限。

 

-------------------------------

 

public static class CursorLoaderListFragment extends ListFragment

        implements OnQueryTextListener, LoaderManager.LoaderCallbacks<Cursor> {

 

    // This is the Adapter being used to display the list's data.

    // 这是适配器,用于显示列表数据。

    SimpleCursorAdapter mAdapter;

 

    // If non-null, this is the current filter the user has provided.

    // 如果非空,它是用户提供的当前过滤器。

    String mCurFilter;

 

    @Override public void onActivityCreated(Bundle savedInstanceState) {

        super.onActivityCreated(savedInstanceState);

 

        // Give some text to display if there is no data.  In a real

        // application this would come from a resource.

        // 指定没有数据时显示的文本。

        // 真实应用程序中它应该取自资源。

        setEmptyText("No phone numbers");

 

        // We have a menu item to show in action bar.

        // 我们有菜单条目要显示在动作栏。

        setHasOptionsMenu(true);

 

        // Create an empty adapter we will use to display the loaded data.

        // 创建空的适配器,我们将用它显示被加载的数据。

        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);

        setListAdapter(mAdapter);

 

        // Prepare the loader.  Either re-connect with an existing one,

        // or start a new one.

        // 准备加载器。要么用现存加载器重连,要么启动新的加载器。

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

    }

 

    @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {

        // Place an action bar item for searching.

        // 放置动作栏条目供搜索。

        MenuItem item = menu.add("Search");

        item.setIcon(android.R.drawable.ic_menu_search);

        item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);

        SearchView sv = new SearchView(getActivity());

        sv.setOnQueryTextListener(this);

        item.setActionView(sv);

    }

 

    public boolean onQueryTextChange(String newText) {

        // Called when the action bar search text has changed.  Update

        // the search filter, and restart the loader to do a new query

        // with this filter.

        // 当动作栏搜索文本被修改时调用。

        // 更新搜索过滤器,并重启加载器以用此过滤器完成新的查询。

        mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;

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

        return true;

    }

 

    @Override public boolean onQueryTextSubmit(String query) {

        // Don't care about this.

        // 不要关心这里

        return true;

    }

 

    @Override public void onListItemClick(ListView l, View v, int position, long id) {

        // Insert desired behavior here.

        // 此处插入所需的行为。

        Log.i("FragmentComplexList", "Item clicked: " + id);

    }

 

    // These are the Contacts rows that we will retrieve.

    // 我们将检索的Contacts的行

    static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {

        Contacts._ID,

        Contacts.DISPLAY_NAME,

        Contacts.CONTACT_STATUS,

        Contacts.CONTACT_PRESENCE,

        Contacts.PHOTO_ID,

        Contacts.LOOKUP_KEY,

    };

    public Loader<Cursor> onCreateLoader(int id, Bundle args) {

        // This is called when a new Loader needs to be created.  This

        // sample only has one Loader, so we don't care about the ID.

        // First, pick the base URI to use depending on whether we are

        // currently filtering.

        // 当新加载器需要被创建时,这个方法被调用。这个示例只有一个加载器,

        // 所以我们不关心ID。首先,根据我们是否正在被过滤,获取要使用的基本URI。

        Uri baseUri;

        if (mCurFilter != null) {

            baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,

                    Uri.encode(mCurFilter));

        } else {

            baseUri = Contacts.CONTENT_URI;

        }

 

        // Now create and return a CursorLoader that will take care of

        // creating a Cursor for the data being displayed.

        // 现在创建和返回CursorLoader对象,它将负责创建用于要显示数据的游标。

        String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND ("

                + Contacts.HAS_PHONE_NUMBER + "=1) AND ("

                + Contacts.DISPLAY_NAME + " != '' ))";

        return new CursorLoader(getActivity(), baseUri,

                CONTACTS_SUMMARY_PROJECTION, select, null,

                Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");

    }

 

    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {

        // Swap the new cursor in.  (The framework will take care of closing the

        // old cursor once we return.)

        // 交换进新的游标。(一旦我们返回,片段将负责关闭旧游标)

        mAdapter.swapCursor(data);

    }

 

    public void onLoaderReset(Loader<Cursor> loader) {

        // This is called when the last Cursor provided to onLoadFinished()

        // above is about to be closed.  We need to make sure we are no

        // longer using it.

        // 当上面提供给onLoadFinished()的最后Cursor对象将要关闭时调用。

        // 我们需要确保我们不再使用它。

        mAdapter.swapCursor(null);

    }

}

 

-------------------------------

 

More Examples

 

更多示例

 

There are a few different samples in ApiDemos that illustrate how to use loaders:

 

在ApiDemos中有一些不同的示例,描述如何使用加载器:

 

* LoaderCursor — A complete version of the snippet shown above.

 

* LoaderCursor——上面展示代码片段的完整版本。

 

* LoaderThrottle — An example of how to use throttling to reduce the number of queries a content provider does when its data changes.

 

* LoaderThrottle——一个例子,演示如何通过减速,降低内容提供者在其数据改变时出现的请求数量。

 

For information on downloading and installing the SDK samples, see Getting the Samples.

 

关于下载和安装SDK示例的信息,请参看示例的获取。

 

Except as noted, this content is licensed under Apache 2.0. For details and restrictions, see the Content License.

 

除特别说明外,本文在Apache 2.0下许可。细节和限制请参考内容许可证。

 

Android 4.0 r1 - 27 Oct 2011 21:16

 

Android 4.0 r1 - 29 Mar 2012 18:25

 

-------------------------------

 

patch:

1. Android 4.0 r1 - 29 Mar 2012 18:25

(1)

reduce the number of queries a content provider does then its data changes.

->

reduce the number of queries a content provider does when its data changes.

 

-------------------------------

 

Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.

 

(此页部分内容基于Android开源项目,以及使用根据创作公共2.5来源许可证中描述的条款进行修改)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值