onLoadFinished не всегда вызывается при перезапуске загрузчика

После того, как пользователь загрузит файлы в облако, я хочу, чтобы приложение перезапустило загрузчик.

Ранее onLoadFinishedне всегда вызывался (случайным образом), когда я писал свой код следующим образом

public void reloadAfterOpenFromCloud() {
    LoaderManager loaderManager = this.getLoaderManager();
    loaderManager.restartLoader(0, bundle, this);
}

После ссылки на обсуждение в Android-onLoadFinished не называется, Я изменяю свой код, чтобы

public void reloadAfterOpenFromCloud() {
    // https://stackoverflow.com/questions/16014992/android-onloadfinished-not-called
    // This seems to be a realiable way, to make sure onCreateLoader and onLoadFinished will
    // be called.
    LoaderManager loaderManager = this.getLoaderManager();
    Loader loader = loaderManager.getLoader(0);
    if (loader != null) {
        loaderManager.destroyLoader(0);
    }
    loaderManager.restartLoader(0, bundle, this);
}

Это уменьшает шанс не звонить onLoadFinished. Тем не менее, это будет случайным образом, если я

  1. Очистите кэш, очистите удаление в моем приложении.
  2. Установите приложение.
  3. Бежать reloadAfterOpenFromCloud. Опять же, случайным образом, onLoadFinishedне будет вызываться.

Когда onLoadFinishedне вызывается, если я бегу reloadAfterOpenFromCloudснова, onLoadFinishedбудет вызван.

Я использую последние com.android.support:support-v4:25.0.0И.targetSdkVersion 25

Мне было интересно, есть ли какой-либо реальный обходной путь, чтобы гарантироватьonLoadFinished, что всегда вызывается, когда загрузчик перезапущен?


Ниже приведены фрагменты моего кода.

public void reloadAfterOpenFromCloud() {
    // https://stackoverflow.com/questions/16014992/android-onloadfinished-not-called
    // This seems to be a realiable way, to make sure onCreateLoader and onLoadFinished will
    // be called.
    LoaderManager loaderManager = this.getLoaderManager();
    Loader loader = loaderManager.getLoader(0);
    if (loader != null) {
        loaderManager.destroyLoader(0);
    }
    loaderManager.restartLoader(0, bundle, this);
}

static class HomeMenuRowInfosLoader extends AsyncTaskLoader<List<HomeMenuRowInfo>> {

    private List<HomeMenuRowInfo> homeMenuRowInfos = null;

    public HomeMenuRowInfosLoader(Context context) {
        super(context);
    }

    @Override
    public List<HomeMenuRowInfo> loadInBackground() {
        ...
        return homeMenuRowInfos;
    }

    /**
     * Handles a request to cancel a load.
     */
    @Override 
    public void onCanceled(List<HomeMenuRowInfo> homeMenuRowInfos) {
        super.onCanceled(homeMenuRowInfos);
    }

    /**
     * Handles a request to stop the Loader.
     * Automatically called by LoaderManager via stopLoading.
     */
    @Override 
    protected void onStopLoading() {
        // Attempt to cancel the current load task if possible.
        cancelLoad();
    }

    /**
     * Handles a request to start the Loader.
     * Automatically called by LoaderManager via startLoading.
     */
    @Override        
    protected void onStartLoading() {
        if (this.homeMenuRowInfos != null) {
            deliverResult(this.homeMenuRowInfos);
        }

        if (takeContentChanged() || this.homeMenuRowInfos == null) {
            forceLoad();
        }
    }

    /**
     * Handles a request to completely reset the Loader.
     * Automatically called by LoaderManager via reset.
     */
    @Override 
    protected void onReset() {
        super.onReset();

        // Ensure the loader is stopped
        onStopLoading();

        // At this point we can release the resources associated with 'apps'
        // if needed.
        this.homeMenuRowInfos = null;
    }        
}

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

// Not being called always when restart loader
@Override
public void onLoadFinished(Loader<List<HomeMenuRowInfo>> arg0, List<HomeMenuRowInfo> homeMenuRowInfos) {
    ...

1 ответ

  1. Вам нужно реализовать какой-то наблюдатель в вашемHomeMenuRowInfosLoader, который будет вызыватьonContentChanged(), когда пользователь закончит передачу файлов облака.

    Если onContentChanged()никогда не вызывается, takeContentChanged()всегда будет возвращаться falseи forceLoad()не будет вызываться внутри onStartLoading()после первой загрузки, в которой точка homeMenuRowInfosне равна null.