自定义AsyncTaskLoader回调问题

时间:2011-08-22 20:30:54

标签: android android-asynctask loader android-loadermanager

我的AsyncTaskLoader遇到了一些问题,不确定它们是否相关,因为它们在尝试重新启动Loader时都会发生。在我的应用程序中,我有3个自定义CursorAdapter实例,由3个由1个singleton LoaderManager管理的自定义AsyncTaskLoader实例支持。这些问题与两个不同的Adapter / Loader对有关,但在每种情况下使用的代码都相同:

getLoaderManager().restartLoader(loaderId, bundle, loaderManager);

问题1:我调用restartLoader()并且LoaderManager注册了对onCreateLoader的调用,但没有注册到onLoaderReset()。 Loader获取deliverResult(),但永远不会调用onLoadFinished()。 Loader既没有设置'reset'或'started'标志(见下面的代码)。

问题2:我调用restartLoader()并且LoaderManager注册了对onLoaderReset()的调用。 Loader获取onReset(),但没有进一步。 Cursor设置为null,但没有加载新的Cursor。

任何想法可能是什么问题?以下是Loader和Loader Manager的一些代码:

CustomCursorLoader.java

@Override
protected void onStartLoading() {
    Log.v(TAG, "Starting Loader");
    if (lastCursor != null) {
        deliverResult(lastCursor);
    }
    if (takeContentChanged() || lastCursor == null) {
        forceLoad();
    }
}

@Override
public void deliverResult(Cursor cursor) {
    Log.v(TAG, "Delivering result");
    if (isReset()) {
        Log.v(TAG, "reset");
        if (cursor != null) {
            cursor.close();
        }
        return;
    }
    Cursor oldCursor = lastCursor;
    lastCursor = cursor;
    if (isStarted()) {
        Log.v(TAG, "started");
        super.deliverResult(cursor);
    }
    if (oldCursor != null && oldCursor != cursor && !oldCursor.isClosed()) {
        oldCursor.close();
    }
}

@Override
protected void onReset() {
    Log.v(TAG, "Reset");
    super.onReset();
    onStopLoading();
    if (lastCursor != null && !lastCursor.isClosed()) {
        lastCursor.close();
    }
    lastCursor = null;
}

CustomCursorLoaderManager.java:

@Override
public Loader<Cursor> onCreateLoader(int loaderId, Bundle bundle) {
    return new CustomCursorLoader();
}

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    cursorAdapter.changeCursor(cursor);
}

@Override
public void onLoaderReset(Loader<Cursor> loader) {
    cursorAdapter.changeCursor(null);
}

2 个答案:

答案 0 :(得分:1)

您所谓的'LoaderManager'实际上是LoaderManager.LoaderCallbacks<D>接口的实现。您可能想要使用其他名称,这个名称令人困惑。为什么它是单身人士?它通常与Activity或Fragment绑定,可能只是实现接口的Activity / Fragment。你在哪里创建你的装载机(活动/片段)?另外,请确保从LoaderManager.initLoader()拨打onCreate()/onActivityCreated(),否则可能无法正常启动加载程序。

答案 1 :(得分:0)

创建游标并将其指向数据库时,不能只将其设置为null。您必须显式关闭游标,否则它将锁定数据库,直到它超时。

我建议利用Android生命周期和现有的回调来实现此修复。

希望这有帮助!