Android の非同期処理を行う Loader の起動方法

公開日: : Android , ,

これ、ボクの完全な思い違いだったのですが、非同期処理を行うクラスの呼び出しは Activity か Fragment だけだと勝手に思い込んでいました。

でも、そうではなくて LoaderManager.LoaderCallbacks<T> インタフェースを実装していれば、非同期処理を行うクラスを呼び出せますよね、ってことを学んだのでメモしておきます。

icatch-error_9849183645_mini

photo credit: Skley via photopin cc

目次

1. 動作環境

動作環境ですが、Android アプリの開発には次の IDE を使っています。

android-2014-02-18-00-1

2. サンプルソースコード

以下がサンプルソースコードになります。

2-1. AbstractAsyncTaskLoader

このクラスは非同期処理を行うクラスの抽象クラスです。

Andoroid アプリ開発は数少ないですが、これで不足が出たことはないので毎回このクラスを継承させています。

import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;

public abstract class AbstractAsyncTaskLoader<T> extends AsyncTaskLoader<T> {
    
    protected T result;

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

    @Override
    abstract public T loadInBackground();
    
    @Override
    public void deliverResult(T data) {
        if(isReset()) {
            return;
        }
        
        result = data;
        if(isStarted()) {
            super.deliverResult(data);
        }
    }

    @Override
    protected void onStartLoading() {
        if(result != null) {
            deliverResult(result);
        }
        
        if(takeContentChanged() || result == null) {
            forceLoad(); // 非同期処理を開始
        }
    }
    
    @Override
    protected void onStopLoading() {
        cancelLoad(); // 非同期処理のキャンセル
    }
    
    @Override
    public void onCanceled(T data) {
        // 特にやることなし
    }
    
    @Override
    protected void onReset() {
        super.onReset();
        
        onStopLoading();
        result = null;
    }
}

2-2. 非同期処理を行うクラス

上記の AbstractAsyncTaskLoader<T> を継承した非同期処理を行うクラスです。

実行処理の結果を Boolean で返します。
本来なら loadInBackground メソッドにて非同期で行う処理を実装するのですが、サンプルなので単純に true を返しています。

import android.content.Context;

public class HogeAsyncTaskLoader extends AbstractAsyncTaskLoader<Boolean> {

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

    @Override
    public Boolean loadInBackground() {
        return Boolean.TRUE;
    }
}

2-3. LoaderManager.LoaderCallbacks を実装したクラス

このクラスが上記 HogeAsyncTaskLoader の生成や、非同期処理の実行結果を使った後処理を行います。

この役割を担えるのは Activity や Fragment だけだと壮大に勘違いしていた役割の人です。

HogeAsyncTaskLoader の非同期処理が Boolean を返すので LoaderManager.LoaderCallbacks<Boolean> インタフェースを実装しています。

import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.util.Log;

public class Hoge implements LoaderManager.LoaderCallbacks<Boolean> {
    
    private static final String TAG = Hoge.class.getSimpleName();
    
    private Context context;

    public Hoge() {}
    
    public Hoge(Context context) {
        this.context = context;
    }

    @Override
    public Loader<Boolean> onCreateLoader(int id, Bundle bundle) {
        Log.d(TAG, "HogeAsyncTaskLoader の生成");

        return new HogeAsyncTaskLoader(context);
    }

    @Override
    public void onLoadFinished(Loader<Boolean> loader, Boolean result) {
        Log.d(TAG, "非同期処理が終わったー");
        
        // 以下に result を使って「後処理」を実装する
    }

    @Override
    public void onLoaderReset(Loader<Boolean> result) {
        // 必要に応じて実装する
    }
    
    public void execute(Fragment fragment) {
        fragment.getActivity().getSupportLoaderManager().initLoader(0, null, this);
    }

}

コンストラクタで Context オブジェクトを受け取っています。
これは、非同期処理の実行に必要になるのでこのようにしています。

最後に定義してある execute メソッドが非同期処理実行のトリガーになります。

関連する Fragment から LoaderManager を Activity 経由で取得して、Loader を初期化することで非同期が起動します。

execute メソッドを実行すると、、、

  1. Hoge#onCreateLoader が呼ばれる → HogeAsyncTaskLoader が new される
  2. HogeAsyncTaskLoader#loadInBackground が実行される

という流れになります。

3. まとめ

確かに LoaderManager.LoaderCallbacks<T> さえ実装していれば非同期処理を呼べる人にはなりますが、結局のところ、処理結果を画面に反映することが多いでしょうから、担当する画面の Activity や Fragment が担当することが多くなりそうです。

4. その他の Android に関する記事

その他の Android に関する記事は次の通りです。
気になる記事があったらぜひチェックしてみてください!

Googleアドセンス用(PC)

  • このエントリーをはてなブックマークに追加
  • follow us in feedly

関連記事

icatch-thread_11187402315_mini

Android アプリ開発で “cannot perform this action inside of onloadfinished” とエラーメッセージが表示された場面の対処法

現在仕事で Android アプリ開発をやっていて、この "cannot perform this

記事を読む

icach-smartphone_10858946293_mini

Android アプリで “external/chromium/net/disk_cache/stat_hub.cc:216″ とエラーメッセージが表示された場合の対処法

Android アプリ開発中にとある画面を表示しようとしたら "external/chromium/

記事を読む

icatch-bar_7241902618_mini

Android アプリで ActionBar の背景色を変更する方法

Android 3.x 系から追加された ActionBar。 開発中の Android アプリで

記事を読む

no image

Android アプリで Google Analytics へトラッキングするサンプルクラス

お客さまからの要望があって対応。特に難しいことはないのだが、せっかくなので Gist にスニペットを

記事を読む

icatch-android_6051805616_mini

Android アプリ開発で “Unable to resolve target ‘android-16′” などとエラーメッセージが表示された場合の対処法

"Unable to resolve target 'android-16'" などとエラーメッセー

記事を読む

no image

AlertDialog の背景をタップできなくする

AlertDialog はモーダルダイアログではないので背景をタップできてしまう。それだとちょっと不

記事を読む

icatch-finished_6609228299_mini

Android アプリで特定の Activity が呼ばれたらアプリを終了させる方法

とある Activity が呼ばれたらアプリを終了させる方法です。 戻るボタンで戻りすぎることが出

記事を読む

no image

AlertDialog がキャンセルされたときに処理を行うスニペット

AlertDialog のスニペット。キャンセル時のリスナーを Gist に登録。 new Al

記事を読む

no image

初めてのアンドロイドアプリ開発振り返り

始めてのアンドロイドアプリ開発が落ち着きをみせてきた。まだ熱が冷めないうちに簡単に振り返っておく。

記事を読む

no image

位置情報取得に関する覚え書き、その2

以前、【Androidアプリ開発】位置情報取得に関する覚え書き を書いたが、試行錯誤を続ける中で変更

記事を読む

Googleアドセンス用(PC)

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


× 9 = 五十 四

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Googleアドセンス用(PC)

icatch-jersey_multi_pathparams
Jerseyの@PathParamはスラッシュの間に複数指定できる

http://hoge-api/user/{id}.{format}

icatch-vagrant_box_customize
VagrantのBoxファイルをカスタマイズして独自のBoxファイルを作成する

配布されている Vagrant の Box ファイルを使って検証環境を

icatch-2015-006-1
バリデーションチェックにJava8のOptionalを使ってスマートに書く(自分比)

Web アプリのバリデーションチェックにアノテーションを使うことが増え

icatch-2015-005-1
ユニットテストの偏りを防ぐ命名規則の付け方

ユニットテスト名に以下の命名規則を付けるようにして二ヶ月ぐらい経った。

icatch-2015-004-1
Vagrantで起動したCentOS上のOctopressをホストOSから確認する設定

タイトルの通りだが、Vagrant を使って起動した CentOS に

→もっと見る

PAGE TOP ↑