Most visited

Recently visited

Added in API level 11

LoaderManager

public abstract class LoaderManager
extends Object

java.lang.Object
   ↳ android.app.LoaderManager


ActivityFragment关联的接口,用于管理与其关联的一个或多个Loader实例。 这有助于应用程序管理与Activity或Fragment生命周期结合的更长时间运行的操作; 最常见的用途是使用CursorLoader ,但是应用程序可以自由编写自己的加载器来加载其他类型的数据。 虽然在HONEYCOMB中引入了LoaderManager API,但API版本也可通过FragmentActivity在较早的平台上使用。 有关更多详细信息,请参阅博文Fragments For All

作为示例,下面是Fragment的完整实现,它显示包含对联系人内容提供者的查询结果的ListView 它使用CursorLoader来管理提供者上的查询。

public static class CursorLoaderListFragment extends ListFragment
        implements OnQueryTextListener, OnCloseListener,
        LoaderManager.LoaderCallbacks<Cursor> {

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

    // The SearchView for doing filtering.
    SearchView mSearchView;

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

        // Start out with a progress indicator.
        setListShown(false);

        // Prepare the loader.  Either re-connect with an existing one,
        // or start a new one.
        getLoaderManager().initLoader(0, null, this);
    }

    public static class MySearchView extends SearchView {
        public MySearchView(Context context) {
            super(context);
        }

        // The normal SearchView doesn't clear its search text when
        // collapsed, so we will do this for it.
        @Override
        public void onActionViewCollapsed() {
            setQuery("", false);
            super.onActionViewCollapsed();
        }
    }

    @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
                | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
        mSearchView = new MySearchView(getActivity());
        mSearchView.setOnQueryTextListener(this);
        mSearchView.setOnCloseListener(this);
        mSearchView.setIconifiedByDefault(true);
        item.setActionView(mSearchView);
    }

    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.
        String newFilter = !TextUtils.isEmpty(newText) ? newText : null;
        // Don't do anything if the filter hasn't actually changed.
        // Prevents restarting the loader when restoring state.
        if (mCurFilter == null && newFilter == null) {
            return true;
        }
        if (mCurFilter != null && mCurFilter.equals(newFilter)) {
            return true;
        }
        mCurFilter = newFilter;
        getLoaderManager().restartLoader(0, null, this);
        return true;
    }

    @Override public boolean onQueryTextSubmit(String query) {
        // Don't care about this.
        return true;
    }

    @Override
    public boolean onClose() {
        if (!TextUtils.isEmpty(mSearchView.getQuery())) {
            mSearchView.setQuery(null, true);
        }
        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.
    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.
        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.
        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);

        // The list should now be shown.
        if (isResumed()) {
            setListShown(true);
        } else {
            setListShownNoAnimation(true);
        }
    }

    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.
        mAdapter.swapCursor(null);
    }
}

Developer Guides

有关使用加载器的更多信息,请阅读 Loaders开发人员指南。

Summary

Nested classes

interface LoaderManager.LoaderCallbacks<D>

客户端与管理器进行交互的回调接口。

Public constructors

LoaderManager()

Public methods

abstract void destroyLoader(int id)

停止并删除具有给定ID的加载程序。

abstract void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args)

将LoaderManager的状态打印到给定的流中。

static void enableDebugLogging(boolean enabled)

控制框架的内部加载器管理器调试日志是否打开。

abstract <D> Loader<D> getLoader(int id)

如果没有找到匹配的加载程序,则返回具有给定标识的Loader或null。

abstract <D> Loader<D> initLoader(int id, Bundle args, LoaderCallbacks<D> callback)

确保加载程序已初始化并处于活动状态。

abstract <D> Loader<D> restartLoader(int id, Bundle args, LoaderCallbacks<D> callback)

在此管理器中启动新的或重新启动现有的 LoaderLoader注册回调,并且(如果活动/片段当前已启动)开始加载它。

Inherited methods

From class java.lang.Object

Public constructors

LoaderManager

Added in API level 11
LoaderManager ()

Public methods

destroyLoader

Added in API level 11
void destroyLoader (int id)

停止并删除具有给定ID的加载程序。 如果此装载程序以前通过onLoadFinished(Loader, Object)向客户报告了数据,则将致电onLoaderReset(Loader)

Parameters
id int

dump

Added in API level 11
void dump (String prefix, 
                FileDescriptor fd, 
                PrintWriter writer, 
                String[] args)

将LoaderManager的状态打印到给定的流中。

Parameters
prefix String: Text to print at the front of each line.
fd FileDescriptor: The raw file descriptor that the dump is being sent to.
writer PrintWriter: A PrintWriter to which the dump is to be set.
args String: Additional arguments to the dump request.

enableDebugLogging

Added in API level 11
void enableDebugLogging (boolean enabled)

控制框架的内部加载器管理器调试日志是否打开。 如果启用,当框架执行加载操作时,您将在logcat中看到输出。

Parameters
enabled boolean

getLoader

Added in API level 11
Loader<D> getLoader (int id)

如果没有找到匹配的加载程序,则返回具有给定标识的Loader或null。

Parameters
id int
Returns
Loader<D>

initLoader

Added in API level 11
Loader<D> initLoader (int id, 
                Bundle args, 
                LoaderCallbacks<D> callback)

确保加载程序已初始化并处于活动状态。 如果加载程序不存在,则创建一个加载程序(如果活动/碎片当前已启动)将启动加载程序。 否则,重新使用最后创建的加载器。

无论哪种情况,给定的回调函数都与加载器相关联,并且随着加载器状态更改而调用。 如果在调用点处调用者处于启动状态,并且所请求的加载器已经存在并且已经生成了其数据,那么将立即调用回调onLoadFinished(Loader , D) (在此函数内部),因此您必须为此做好准备。

Parameters
id int: A unique identifier for this loader. Can be whatever you want. Identifiers are scoped to a particular LoaderManager instance.
args Bundle: Optional arguments to supply to the loader at construction. If a loader already exists (a new one does not need to be created), this parameter will be ignored and the last arguments continue to be used.
callback LoaderCallbacks: Interface the LoaderManager will call to report about changes in the state of the loader. Required.
Returns
Loader<D>

restartLoader

Added in API level 11
Loader<D> restartLoader (int id, 
                Bundle args, 
                LoaderCallbacks<D> callback)

开始一个新的或重新启动该管理器中的现有LoaderLoader注册回调,并且(如果活动/片段当前已启动)开始加载它。 如果以前已经启动了一个具有相同ID的加载器,那么当新加载器完成其工作时,它将自动被销毁。 回调将在旧加载器销毁之前交付。

Parameters
id int: A unique identifier for this loader. Can be whatever you want. Identifiers are scoped to a particular LoaderManager instance.
args Bundle: Optional arguments to supply to the loader at construction.
callback LoaderCallbacks: Interface the LoaderManager will call to report about changes in the state of the loader. Required.
Returns
Loader<D>

Hooray!