LoaderManager.restartLoader()总是会调用onCreateLoader()吗?

Maa*_*ten 15 android android-loadermanager android-loader

LoaderManager有这个方法restartLoader():

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

在此管理器中启动新的或重新启动现有的Loader,向其注册回调,并且(如果活动/片段当前已启动)开始加载它.如果先前已启动具有相同id的加载器,则在新加载器完成其工作时将自动销毁该加载器.回调将在旧的加载器被销毁之前传递.

基于开发指南,我得到的结论是,确实,调用onCreateLoader将始终来自restartLoader():

重新启动加载程序

...

要丢弃旧数据,请使用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;
}

public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    // NOTE: The Loader is instantiated with the user's query

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

在该示例中,onCreateLoader唯一的地方是将有关用户查询的信息传递给Loader(在实例化时).然而,文档通过说"启动新的或重新启动现有的Loader " 来解雇我.

Nig*_*elK 29

对你的问题的简单回答是肯定的,对restartLoader()的调用将再次调用onCreateLoader().

你可以并行启动多个加载器(比如你有两个SimpleCursorAdapters来填充),例如:

getLoaderManager().initLoader(0, null, this);  //id = 0
getLoaderManager().initLoader(1, null, this);  //id = 1
Run Code Online (Sandbox Code Playgroud)

然后,Loader Manager为每个id调用onCreateLoader(然后由Loader Manager异步构建返回的加载器):

public Loader<Cursor> onCreateLoader(int id, Bundle args)
{
    if (id == 0)
        //return a Loader<Cursor> for id 0
    else if (id == 1)
        //return a Loader<Cursor> for id 1
}
Run Code Online (Sandbox Code Playgroud)

Loader Manager将生成的加载器传递给onLoadFinished:

public void onLoadFinished(Loader<Cursor> loader, Cursor cursor)
{
    if (loader.getId() == 0)
        //cursor was returned from onCreateLoader for id 0
        //perhaps do swapCursor(cursor) on an adapter using this loader
    else if (loader.getId() == 1)
        //cursor was returned from onCreateLoader for id 1
        //perhaps do swapCursor(cursor) on an adapter using this loader
}
Run Code Online (Sandbox Code Playgroud)

当您随后调用重启加载程序时:

getLoaderManager().restartLoader(0, null, this);  //id = 0
Run Code Online (Sandbox Code Playgroud)

...首先调用onLoaderReset:

public void onLoaderReset(Loader<Cursor> loader)
{
    if (loader.getId() == 0)
        //perhaps do swapCursor(null) on an adapter using this loader
    else if (loader.getId() == 1)
        //perhaps do swapCursor(null) on an adapter using this loader
}
Run Code Online (Sandbox Code Playgroud)

...然后是对onCreateLoader的新调用.所以在这方面,onCreateLoader既用于启动全新的加载器,也用于重置现有的加载器.