【问题标题】:Android - onLoadFinished not calledAndroid - 未调用 onLoadFinished
【发布时间】:2013-04-15 12:19:32
【问题描述】:

我遇到了 Loader 的问题。

我有一个活动,它显示从本地数据库检索到的记录列表。当活动开始时,记录会通过 LoaderManager.initLoader() 方法自动加载。

还可以通过 ActionBarSherlock 中的刷新按钮手动刷新列表。但是,在完成另一个向 DB 添加记录的活动后,不会调用 onLoadFinished。

我正在使用SimpleCursorLoader,这是来自活动的代码 sn-p:

@Override
public void onStart() {
   ...
   getSupportLoaderManager().initLoader(0, null, this);
}

@Override
public void onPause() {
   ...
   getSupportLoaderManager().destroyLoader(0);
}

public void refreshRecords() {
   getSupportLoaderManager().restartLoader(0, null, this);
}

@Override
public Loader<Cursor> onCreateLoader(int id, final Bundle args) {
Loader<Cursor> l = new SimpleCursorLoader(this) {
    @Override
    public Cursor loadInBackground() {
        return recordDAO.getCursor();
    }
};
l.forceLoad();
return l;
}

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor c) {
   // updateUI
}

@Override
public void onLoaderReset(Loader<Cursor> loader) {
}

问题是在完成其他活动后,onLoaderCreate 被调用,但onLoaderFinished 未被调用。

经过一些调试,我发现SimpleCursorAdapter.deliverResults() 也被调用了,bud 最终在.. if (isReset()) { ..

我错过了什么吗?如何强制重新加载数据?

提前谢谢你

【问题讨论】:

标签: android android-loadermanager android-loader


【解决方案1】:

感谢上的讨论,我终于找到了解决这个问题的方法

https://groups.google.com/forum/#!topic/android-developers/DbKL6PVyhLI

public static <T> void initLoader(final int loaderId, final Bundle args, final LoaderCallbacks<T> callbacks,
        final LoaderManager loaderManager) {
    final Loader<T> loader = loaderManager.getLoader(loaderId);
    if (loader != null && loader.isReset()) {
        loaderManager.restartLoader(loaderId, args, callbacks);
    } else {
        loaderManager.initLoader(loaderId, args, callbacks);
    }
}

除了支持库 28 之外,请确保您不要从 Fragment.onCreate() 中调用 initLoader。正如更新的文档所述

您通常在活动的onCreate() 方法或片段的onActivityCreated() 方法中初始化加载器。

https://developer.android.com/guide/components/loaders

【讨论】:

  • 为我工作。谢谢。
  • 几乎是正确的解决方案:正如groups.google.com/forum/#!topic/android-developers/DbKL6PVyhLI 中提到的(并且我进行了实验),重置条件是 !loader.isReset() ,即,'如果加载器是,你应该只重启加载器不重置。 (由艾蒂安撰写)。请更新您的答案。
【解决方案2】:

RaB 解决方案对我不起作用

我的工作解决方案,总是在重启前销毁加载器

Loader<Cursor> loader = mLoaderManager.getLoader(mKeyLoader);
if (loader != null)
{
    mLoaderManager.destroyLoader(mKeyLoader);
}
mLoaderManager.restartLoader(mKeyLoader, args, this);

【讨论】:

  • 谢谢。我终于找到了为什么要强制加载程序总是调用 onLoadFinished 方法。
【解决方案3】:

除了 RaB 的回答之外,如果您使用的是自定义 Loader,请确保如果您调用 super 如果您覆盖 deliverResult()

@Override
public void deliverResult(D data) {
    super.deliverResult(data); // <--onLoadFinished() will not be called if you don't call this
    ...
}

【讨论】:

    【解决方案4】:

    fwiw,在调用第一个 onLoadFinished 之前,我尝试第二次立即重新启动加载程序时遇到了类似的问题,导致两者都没有被调用。

    这对我有用:

    if( loader == null )
        loader = loaderMngr.initLoader(
            0, null, myLoaderCallbacks
            ); 
    else if( loader.isAbandoned() )
        return;
    else
        loaderMngr.restartLoader(
            0, null, myLoaderCallbacks
            );    
    

    【讨论】:

      【解决方案5】:

      检查支持库。使用此导入 android.support.v4.app。不要使用 android.app.loadermanager。

      import android.support.v4.app.LoaderManager;
      import android.support.v4.content.CursorLoader;
      import android.support.v4.content.Loader;
      

      初始化部分

          LoaderManager mLoaderManager=getSupportLoaderManager(); 
      
            LoaderManager.LoaderCallbacks<Cursor> mCursorLoaderCallbacks=new LoaderManager.LoaderCallbacks<Cursor>() {
                      @Override
                      public Loader<Cursor> onCreateLoader(int id, Bundle cursor) {
                            return new CursorLoader(getActivity(), MediaStore.Video.Media.EXTERNAL_CONTENT_URI, COLUMNS_OF_INTEREST, null, null,
                                  MediaStore.Video.Media.DATE_ADDED + " DESC");
                      }
                      @Override
                      public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
                      }
      
      
                      @Override
                      public void onLoaderReset(Loader<Cursor> loader) {              
                     }
                  };
      
        mLoaderManager.initLoader(URL_LOADER_EXTERNAL, null, mCursorLoaderCallbacks);
      

      【讨论】:

      • 工作。谢谢!
      猜你喜欢
      • 2013-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多