‘FragmentActivity’ タグのついている投稿

AsyncTaskLoaderのあるActivityに戻ってきたときに再度loadInBackgroundが呼ばれる問題

最近はもっぱらAndroidのSupport LibraryでFragmentActivityな日々ですが、AsyncTaskLoaderが良いというウワサなのでAsyncTaskを置き換える程度の気持ちで使ったらガッツリハマりました。

今回の問題はAsyncTaskLoaderを実装したActivityから他のActivityに移動し、戻るボタンで戻ってきたときに勝手にloadInBackgroundが実行されてしまう問題です。

結論としては、何も考えずに以下サイトのdeliverResult以下全部自分のAsyncTaskLoaderにコピーしておけばいいです。

android – onLoadFinished not called after coming back from a HOME button press – Stack Overflow

一応転載しておきます。

public abstract class AsyncLoader<D> extends AsyncTaskLoader<D> {

    private D data;

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

    @Override
    public void deliverResult(D data) {
        if (isReset()) {
            // An async query came in while the loader is stopped
            return;
        }

        this.data = data;

        super.deliverResult(data);
    }


    @Override
    protected void onStartLoading() {
        if (data != null) {
            deliverResult(data);
        }

        if (takeContentChanged() || data == null) {
            forceLoad();
        }
    }

    @Override
    protected void onStopLoading() {
         // Attempt to cancel the current load task if possible.
        cancelLoad();
    }

    @Override
    protected void onReset() {
        super.onReset();

        // Ensure the loader is stopped
        onStopLoading();

        data = null;
    }
}

この例では抽象クラスなので同じようなことをする場合はAsyncLoaderをextendsすればいいですね。

こちらも大体同じ構成のようです。

時代は AsyncTask より AsyncTaskLoader – ぐま あーかいぶ

呼び出しに時間のかかるサーバサイドのAPIの処理に利用しようとして、ActivityのonCreateで

getSupportLoaderManager().initLoader(0, null, mCallbacks);

として、呼び出しのたびに

        Bundle bundle = new Bundle(1);
        bundle.putString(KEY_PARAM_1, "something");
        getSupportLoaderManager().restartLoader(0, bundle, mCallbacks);

として呼び出していました。

戻るボタンで戻ってくると、これらを通らずにLoaderがonStartLoadingを実行するので、ここでforceLoadを実行していると、loadInBackgroundが実行されてしまいます。

まぁ、結局問題は条件をつけずに

    @Override
    protected void onStartLoading() {
        forceLoad();
    }

にしてしまっていたことなので、気をつけましょうという話です。

Loaderは概念もうちょっと理解しないと、危ないですね。