コンパチライブラリを使用してです。(未だに2系だけしか持ってません( ー`дー´)キリッ)
動作させたのは2.2のエミュレータとDesire(2.2)とINFOBAR(2.3)
以下参考サイト
時代はAsyncTaskよりAsyncTaskLoader
ソフトウェア技術ドキュメントを勝手に日本語化
サンプルはこちら
githubじゃなくてスミマセン。
単に指定した秒数待ってランダムに値をぶん投げるだけのものですが…
https://bitbucket.org/daneko/asynctaskloadercheck
まあ今までAsyncTaskは使わずに自前でThread書いたりHandlerに投げたりばっかしてました…
なのでこれからは時代の流れにそってAsyncTaskLoaderを使いたいと思います。
で終わるんだったらこのエントリーはしません。
以下ハマった現象
画面回転を行なうと「FragmentActivityから生成されたLoader側はなぜかおかしい挙動をする」
Fragment#getLoaderManagerで生成したものは期待通りの動きをするんですが…
何を言っているのかわか(ry
とりあえずおもむろにログを晒す
02-05 18:36:30.732: D/jp.omokageru.dnk.loader.HelloLoaderActivity(613): onButtonClick 02-05 18:36:30.732: V/LoaderManager(613): initLoader in LoaderManager{44f79998 in HelloLoaderActivity{44f43928}}: args=Bundle[{sleeptime=2000}] 02-05 18:36:30.741: D/jp.omokageru.dnk.loader.HelloLoaderActivity(613): onCreateLoader 02-05 18:36:30.741: D/jp.omokageru.dnk.loader.CheckLoader(613): CheckLoader 02-05 18:36:30.741: V/LoaderManager(613): Starting: LoaderInfo{44f7adb0 #0 : CheckLoader{44f7af20}} 02-05 18:36:30.741: D/jp.omokageru.dnk.loader.CheckLoader(613): onStartLoading 02-05 18:36:30.771: V/LoaderManager(613): Created new loader LoaderInfo{44f7adb0 #0 : CheckLoader{44f7af20}} 02-05 18:36:30.781: D/jp.omokageru.dnk.loader.CheckLoader(613): loadInBackground 02-05 18:36:32.786: V/LoaderManager(613): onLoadComplete: LoaderInfo{44f7adb0 #0 : CheckLoader{44f7af20}} 02-05 18:36:32.786: V/LoaderManager(613): onLoadFinished in CheckLoader{44f7af20 id=0}: String{44f7e390} 02-05 18:36:32.791: D/jp.omokageru.dnk.loader.HelloLoaderActivity(613): onLoadFinished 02-05 18:36:32.791: D/jp.omokageru.dnk.loader.HelloLoaderActivity(613): loader:CheckLoader{44f7af20 id=0} 02-05 18:36:32.791: D/jp.omokageru.dnk.loader.HelloLoaderActivity(613): data:Finish9 02-05 18:36:42.191: V/LoaderManager(613): Retaining in LoaderManager{44f79998 in HelloLoaderActivity{44f43928}} 02-05 18:36:42.191: V/LoaderManager(613): Retaining: LoaderInfo{44f7adb0 #0 : CheckLoader{44f7af20}} 02-05 18:36:42.191: V/LoaderManager(613): Destroying Inactive in LoaderManager{44f79998 in HelloLoaderActivity{44f43928}} 02-05 18:36:42.291: V/LoaderManager(613): Finished Retaining in LoaderManager{44f79998 in HelloLoaderActivity{44f813a0}} 02-05 18:36:42.331: V/LoaderManager(613): Finished Retaining: LoaderInfo{44f7adb0 #0 : CheckLoader{44f7af20}} 02-05 18:36:42.331: V/LoaderManager(613): Stopping: LoaderInfo{44f7adb0 #0 : CheckLoader{44f7af20}} 02-05 18:36:46.451: D/jp.omokageru.dnk.loader.HelloLoaderActivity(613): onButtonClick 02-05 18:36:46.451: V/LoaderManager(613): restartLoader in LoaderManager{44f79998 in HelloLoaderActivity{44f813a0}}: args=Bundle[{sleeptime=2000}] 02-05 18:36:46.451: V/LoaderManager(613): Making last loader inactive: LoaderInfo{44f7adb0 #0 : CheckLoader{44f7af20}} 02-05 18:36:46.451: D/jp.omokageru.dnk.loader.HelloLoaderActivity(613): onCreateLoader 02-05 18:36:46.451: D/jp.omokageru.dnk.loader.CheckLoader(613): CheckLoader 02-05 18:36:51.482: V/LoaderManager(613): Retaining in LoaderManager{44f79998 in HelloLoaderActivity{44f813a0}} 02-05 18:36:51.491: W/LoaderManager(613): Called doRetain when not started: LoaderManager{44f79998 in HelloLoaderActivity{44f813a0}} 02-05 18:36:51.491: W/LoaderManager(613): java.lang.RuntimeException: here 02-05 18:36:51.491: W/LoaderManager(613): at android.support.v4.app.LoaderManagerImpl.doRetain(LoaderManager.java:733) 02-05 18:36:51.491: W/LoaderManager(613): at android.support.v4.app.FragmentActivity.onReallyStop(FragmentActivity.java:634) 02-05 18:36:51.491: W/LoaderManager(613): at android.support.v4.app.FragmentActivity.doReallyStop(FragmentActivity.java:616) 02-05 18:36:51.491: W/LoaderManager(613): at android.support.v4.app.FragmentActivity.onRetainNonConfigurationInstance(FragmentActivity.java:442) 02-05 18:36:51.491: W/LoaderManager(613): at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3617) 02-05 18:36:51.491: W/LoaderManager(613): at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3673) 02-05 18:36:51.491: W/LoaderManager(613): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3789) 02-05 18:36:51.491: W/LoaderManager(613): at android.app.ActivityThread.access$2400(ActivityThread.java:125) 02-05 18:36:51.491: W/LoaderManager(613): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2037) 02-05 18:36:51.491: W/LoaderManager(613): at android.os.Handler.dispatchMessage(Handler.java:99) 02-05 18:36:51.491: W/LoaderManager(613): at android.os.Looper.loop(Looper.java:123) 02-05 18:36:51.491: W/LoaderManager(613): at android.app.ActivityThread.main(ActivityThread.java:4627) 02-05 18:36:51.491: W/LoaderManager(613): at java.lang.reflect.Method.invokeNative(Native Method) 02-05 18:36:51.491: W/LoaderManager(613): at java.lang.reflect.Method.invoke(Method.java:521) 02-05 18:36:51.491: W/LoaderManager(613): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 02-05 18:36:51.491: W/LoaderManager(613): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 02-05 18:36:51.491: W/LoaderManager(613): at dalvik.system.NativeStart.main(Native Method)
ログを見たら破棄したローダを再利用して落ちているように見えます。
発生させる挙動としては以下
- アプリを立ち上げる
- AsyncTaskLoaderを実行する
- 結果を見る
- 画面回転する
- AsyncTaskLoaderを実行する
- onCreateLoaderで止まる(なぜ…)
- 再度画面回転する
- 上記ログが出る
回避方法はわかった範囲では以下2つ
- 画面回転時Activityを破棄しないようにする(単に逃げる)
- onCreate時にFragmentActivity#getSupportLoaderManagerを呼び出す(なぜうまく行くのかわからん…)
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // ここでの呼び出しを無くすとなぜか画面回転後は動作しなくなる // しかもonCreate以外での呼び出しは駄目っぽい getSupportLoaderManager(); }
ただ画面回転で起こるということは、状況によってはIntentなんかで画面遷移した際にも
起こりそうで嫌です…
destroyまで走れば一緒かな…
Fragment#getLoaderManagerもFragmentActivity#getSupportLoaderManagerも
結局はFragmentActivity#getLoaderManagerを呼んでいますしなんでなんだろ
どっちもonDestroy時にLoaderManager#doDestroy呼んでいるし
何れにしても、なんかうまくいきませんでした。
「使い方がおかしいだろ」とかあったら教えてください。
0 件のコメント:
コメントを投稿