Android AsyncTaskLoader 最小構成での使い方

アンドロイドのアプリを作るにあたって、HTTP通信でウェブサービスなどから json や xml などのデータを取ってきたい。メインスレッドで URL を投げると android.os.NetworkOnMainThreadException が発生するし、UI がフリーズしないよう非同期で処理したい。そんなわけで、ローダのサブクラス AsyncTaskLoader

ローダの最小構成

  • LoaderManager : Loader インスタンス管理に
  • LoaderManager.LoaderCallbacks : ローダの作成、参照の管理
  • AsyncTaskLoader : 非同期処理用の抽象的ローダ。

ローダの初期化

fragment の onActivityCreated でローダマネージャをゲット。ローダを初期化。

@Override
public void onActivityCreated(Bundle savedInstanceState){
  super.onActivityCreated(savedInstanceState);
  getLoaderManager().initLoader(0, null, this);
}

initLoader() のパラメータ

  • 識別用ID:ココでは 0
  • 任意の引数:ココでは null
  • LoaderCallbacks の実装:ココではローカルクラスで実装するので this

LoaderCallbacks の実装必須なアブストラクトメソッド

  • onCreateLoader():ローダ作成時の処理。
  • onLoadFinished():ロードが終了したときの処理。
  • onLoaderReset():ローダがリセットされたときの処理。

型のオブジェクト<Object>は、適宜<String>等に変更を。

onCreateLoader()

return で new ローダのインスタンスを返す。

@Override
public Loader<Object> onCreateLoader(int id, Bundle args) {
  return new MyAsyncTaskLoader(getContext());
}

MyAsyncTaskLoader は、AsyncTaskLoader のサブクラス。後ほど登場。

onLoadFinished()

ログに結果を出力。

@Override
public void onLoadFinished(Loader<Object> loader, Object data) {
  Log.d("result", data.toString());
}

Andoroid Monitor > logcat > Debug に表示。

onLoaderReset()

今回は何もせず。

@Override
public void onLoaderReset(Loader<Object> loader) {

}

AsyncTaskLoader

必須項目

  • onStartLoading():ロード開始時の処理をココに
  • loadInBackground():非同期処理の実体をココに

onStartLoading()

forceLoad() でロードを強制開始。

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

本来はココでキャッシュのチェックなどをするのだが、今回は最小構成なので省略。

loadInBackground()

バックグラウンドで処理したいコードを記し、結果を返す。

@Override
pubulic Object loadInBackground() {

// httpリクエストなどをココに。

  return Object;
}

Fragment にまとめ

Android HTTP通信でウェブサービスからJSONなどのデータをダウンロードしたい で作った HTTP リクエストやMyAsyncTaskLoaderを含めてフラグメントにまとめると↓

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.AsyncTaskLoader;
import android.support.v4.content.Loader;
import android.util.Log;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class HttpGetFragment extends Fragment implements LoaderManager.LoaderCallbacks<String> {


    public HttpGetFragment() {
        // スマホをタテヨコした時用、空のコンストラクタ
    }


    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        getLoaderManager().initLoader(0, null, this);
    }

    @Override
    public Loader<String> onCreateLoader(int id, Bundle args) {
        return new MyAsyncTaskLoader(getContext());
    }

    @Override
    public void onLoadFinished(Loader<String> loader, String data) {
        Log.d("result",data);
    }

    @Override
    public void onLoaderReset(Loader<String> loader) {

    }
}

class MyAsyncTaskLoader extends AsyncTaskLoader {
    MyAsyncTaskLoader(Context context) {
        super(context);
    }

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

    @Override
    public Object loadInBackground() {
        StringBuilder stringBuilder = new StringBuilder();

        try {
            // ココに web service url
            URL url = new URL("https://www.googleapis.com/books/v1/volumes?q=android");
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            BufferedReader bufferedReader
                    = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));

            String line = null;
            while ((line = bufferedReader.readLine()) != null) {
                stringBuilder.append(line);
            }
            bufferedReader.close();
            urlConnection.disconnect();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return stringBuilder.toString();
    }
}

お疲れ様でした。( ^^) _旦~~

“Android AsyncTaskLoader 最小構成での使い方” への1件の返信

コメントを残す

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