FragmentでAsyncTaskLoaderを使ってみる

ネットワーク経由でJSONファイルを取得する実装をしてたんですが、ネットワークアクセスのpermissionも設定しているのになぜか例外投げられてうまく動かなかったんですが、そういえばHoneyComb以降では、ネットワークアクセスをする場合、UIスレッド以外からという制約ができていて、それを回避するためにはAsyncTaskを使わないとダメですよという話を前に聞いたなーと思ったんで、AsyncTaskでネットワークアクセス部分を実装してみました。

しかし、受け取った内容をDBにいれてListViewにセットしたAdapterの更新どうすんだろうとしばらく悩んでたところ、AsyncTaskLoader使うと処理終わったときにUIスレッド側のcallbackメソッド呼べますよっていう話なんで、その方が楽そうなのでそっち使ってみることにしました。

まずは、いままで使っていたクラスの変更を。

extends AsyncTask<?,?,?>

になっているところを

extends AsyncTaskLoader<?>

に書き換え。

loadInBackgroundの引数は必要なくなるので削除。onStartLoadingが必要になるので追加。

loadInBackgroundで使っていた引数は、コンストラクタに引数で渡してメンバー変数に変更。

Fragment側にimplements LoaderCallbacks<?>を追加すれば、Eclipseの補完機能(unimplemented methodsとかいうアレ)で必要なメソッドのひな形が追加されるので、そこに今まであった処理(onLoadFinished)を移動。

onCreateLoaderには、AsyncTaskLoader用クラスのコンストラクタの呼び出しを書いて終わり。

 

このLoaderを呼び出す場合は、getSupportLoaderManagerを使うのでFragmentActivityを使うという説明を読んだけど、FragmentActivity使ってないし、Fragmentにはそんなメソッドがないのでダメなのかと思っていたら、getLoaderManagerというメソッドがあったので気にせずこちらを使ってみたら問題なく動いている。あとでメソッドの説明文読んだら、いっしょの文章だったから、気にしないことにした。

 

getSupportLoaderManagerもgetLoaderManagerも。・・LoaderManagerを取ってくるメソッドだから当たり前かもしれないけど、どちらもinitLoaderが使えるので、

getLoaderManager().initLoader(int, Bundle, LoaderCallbacks<?>)

で呼び出せば、別スレッドで処理が走る。

 

処理が終わったらcallbackでonLoadFinishedが呼び出される。

受け取ったデータをDBにいれたら、CursorLoader.loadInBackgroundを呼び出して、mAdapter.swapCursorでCursorを更新すれば、ListViewも更新される、と。

 

これで動いているので、この件は一応の決着。

広告

About sato_c

小学生の頃にインベーダーゲームやPC-8001やApple][といったものを知ってしまい、それ以降ずーっとゲーム好き。でも、あんまりうまくはありません。 仕事は当初はゲーム関係のプログラムやサウンドをやっていましたが、WEB関係を通ったあと、遊技機関係のプログラムやサウンドをやっています。あまり節操がないのか。 現在はJavaですてきなコードを書けるように勉強中。

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。