アンドロイドのアプリを作るにあたって、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(); } }
お疲れ様でした。( ^^) _旦~~
コメントを残す