restartLoader和onContentChanged之间的区别

时间:2013-05-24 05:32:21

标签: android android-loadermanager android-loader

目前,我有一个装载机

@Override
public Loader<List<HomeMenuRowInfo>> onCreateLoader(int arg0, Bundle bundle) {
    return new HomeMenuRowInfosLoader(this.getSherlockActivity());
}

有时,由于内容更改,我需要让加载程序重新加载。我会这样做。

this.getLoaderManager().getLoader(0).onContentChanged();

但是,当内容发生变化时,我想将一些额外的捆绑信息传递给onCreateLoader回调。我意识到使用onContentChanged,没有办法这样做。

我能想出的唯一方法是

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

我想知道,Loader使用restartLoader代替onContentChanged的行为是否有任何重大差异,除了传递捆绑的能力之外?

3 个答案:

答案 0 :(得分:4)

我认为,主要区别在于restartLoader方法会破坏具有相同ID的旧加载器并启动一个新加载器,而onContentChanged方法会强制加载加载({{1或者只是设置一个标志,指示加载器停止时内容已更改。在第二种情况下,加载器的“所有者”在内容发生变化后仍然负责其(重新)加载。我认为这是由forceLoad自动完成的loaderManager

如果您决定使用restartLoader方法,则应记住旧加载程序的破坏以及对应用程序可能产生的影响,例如缓慢重新初始化等。

您可以查看方法文档以获取更多信息 - restartLoaderonContentChanged

另请注意,旧的装载机在 新装载机完成其工作时被销毁

答案 1 :(得分:1)

状态图应该有助于理解如何使用API​​。我第一次也花了很多时间让图片清晰。用我的工作!

文章:https://plus.google.com/117981280628062796190/posts/8b9RmQvxudb

Loader States Diagram

答案 2 :(得分:0)

每次想要新数据时都要调用restartLoader,或者想要更改游标的参数。

如果您使用initLoader加载数据

lm = fragment.getLoaderManager();
lm.initLoader(LOADER_ID_LIST, null, this);

每次调用initLoader都会将同一光标返回onLoadFinished。只有在第一次调用initLoader时才会调用onCreateLoader方法。因此,您无法更改查询。您将相同的游标与onLoadFinished方法相同的数据。

@Override
public void onLoadFinished(
        android.support.v4.content.Loader<Cursor> loader, Cursor cursor) {
    switch (loader.getId()) {
    case LOADER_ID_LIST:
        // The asynchronous load is complete and the data
        // load a list of
        populateFromCursor(cursor);
        break;
    case LOADER_ID_ENTRY:
        populateFromCursor(cursor);
        break;
    }
    // The listview now displays the queried data.
}

因此,要将新的游标数据添加到onLoadFinished使用restartLoader,您可以根据需要传递捆绑信息。下面我传递null,因为有一个全局变量可用。

lm = fragment.getLoaderManager();
lm.restartLoader(LOADER_ID_LIST, null, this);

然后,loaderManager将调用onCreateLoaderMethod

@Override
public android.support.v4.content.Loader<Cursor> onCreateLoader(int id,
        Bundle args) {

    android.support.v4.content.Loader<Cursor> ret = null;

    // Create a new CursorLoader with the following query parameters.
    switch (id) {

    // load the entire list
    case LOADER_ID_LIST:
        String sortOrder = null;
        switch (mSortOrder) {
        case 0:
            sortOrder = RidesDatabaseHandler.KEY_DATE_UPDATE + " desc";
            break;
        case 1:
            sortOrder = RidesDatabaseHandler.KEY_ID + " desc";
            break;
        case 2:
            sortOrder = RidesDatabaseHandler.KEY_NAME;
        }
        return new CursorLoader(context, RidesDatabaseProvider.CONTENT_URI,
                PROJECTION, null, null, sortOrder);

        // load a single item
    case LOADER_ID_ENTRY:
        sortOrder = null;
        String where = RidesDatabaseHandler.KEY_ID + "=?";

        String[] whereArgs = new String[] { Integer.toString(lastshownitem) };

        return new CursorLoader(context, RidesDatabaseProvider.CONTENT_URI,
                PROJECTION, where, whereArgs, null);
    }
    return ret;
}

注意:除非您确实需要从之前的查询返回的相同数据,否则您不必每次都拨打initLoader来致电restartLoader。您不必致电onContentChanged(),而docs表示Loader.ForceLoadContentObserver已完成。