Проблема с пользовательскими обратными вызовами AsyncTaskLoader - PullRequest
6 голосов
/ 23 августа 2011

У меня возникла пара проблем с моим AsyncTaskLoader, я не уверен, связаны ли они, так как они оба возникают при попытке перезапустить загрузчик.В моем приложении у меня есть 3 экземпляра пользовательского CursorAdapter, поддерживаемого 3 экземплярами пользовательского AsyncTaskLoader, управляемого 1 одноэлементным LoaderManager.Проблемы связаны с двумя различными парами адаптер / загрузчик, но используемый код одинаков для каждого случая:

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

Проблема 1: я вызываю restartLoader (), а LoaderManager регистрирует вызов onCreateLoader, но неодин для onLoaderReset ().Загрузчик получает метод deliveryResult (), но onLoadFinished () никогда не вызывается.В загрузчике не установлены ни флаги «сброс», ни «запуск» (см. Код ниже).

Проблема 2: я вызываю restartLoader (), а LoaderManager регистрирует вызов onLoaderReset ().Загрузчик попадает в onReset (), но дальше не идет.Курсор установлен в ноль, но новый Курсор не загружен.

Есть идеи, в чем может быть проблема?Вот некоторый код для менеджера загрузчика и загрузчика:

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 ]

1 голос
/ 23 августа 2011

То, что вы называете «LoaderManager», на самом деле является реализацией интерфейса LoaderManager.LoaderCallbacks<D>. Возможно, вы захотите использовать другое имя, это сбивает с толку. Почему это синглтон? Обычно он связан с действием или фрагментом, возможно, только с действием / фрагментом, реализующим интерфейс. Где вы создаете свои загрузчики (активность / фрагмент)? Также убедитесь, что вы звоните LoaderManager.initLoader() с onCreate()/onActivityCreated(), иначе загрузчик может не запуститься должным образом.

0 голосов
/ 23 августа 2011

Когда вы создаете курсор и указываете его на базу данных, вы не можете просто установить его на ноль. Вы должны явно закрыть курсор, иначе он заблокирует базу данных до истечения времени ожидания.

Я рекомендую использовать преимущества жизненного цикла Android и ваших существующих обратных вызовов для реализации этого исправления.

Надеюсь, это поможет!

...