前人未踏の領域へ アプリ開発編

Android, iOSアプリ開発に関する調査メモ置き場。ほとんどAndroid。古い記事にはアプリ以外も含まれます。

Android: Intent.ACTION_MY_PACKAGE_REPLACEDを過信するべからず

課題

Room採用のためRealmDBからSQLiteにDBを移行するにあたり、BroadcastReceiverIntent.ACTION_MY_PACKAGE_REPLACED イベントを受取って、そのタイミングでデータ移行プログラムを実行させるようにしたところ、一部の端末でデータが消えたとの報告があった。

対応

Realmマイグレーション時にエラーが発生しているケースを除くと、データ移行のプログラム自体が発動していない可能性がある。そこで BroadcastReceiverのイベント受信からApplicationクラスのonCreateに処理を移動し、そこからWorkManagerOneTimeWorkRequestを作成してenqueueUniqueWorkで重複実行されないようにしたところ、無事データ移行が行われた。

まとめ

Play Storeでアプリが更新されたとしても、(端末によっては?)必ずしもIntent.ACTION_MY_PACKAGE_REPLACEDが発動するとは限らない。
重要度の高い処理はそのタイミングのみに頼らず確実に実行される場所に書くこと。

ViewPager2で操作性が悪化した件(その2)

内容

ViewPager2を導入したら子FragmentのSwipeRefreshLayoutによる縦スワイプ中にグラグラと横スワイプが発生するようになった。

対策

SwipeRefreshLayout自身のイベントリスナーなどを探すと存在せず、無駄に時間を浪費することになる。
正解(?)はSwipeRefreshLayoutを1.1.0以上にすること。

implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"

これで治った気がする。 このandroidxの部品ごとにバージョンが切られてるやつ、 どれが必要でどれが気にしなくていいのかが謎過ぎる。

IllegalStateExceptionが増えた件

内容

最近リリースしたアプリのFirebase Crashlyticsをみると IllegalStateException が妙に増加していた。

メッセージをみると

XXXFragment not associated with a fragment manager が書いてあるんだけど、 なんでこのタイミングで起こるの?という感じの箇所が多い。

onActivityResultがduplicatedになったのを修正した関係で発生しているのだろうか。

もぐら叩き的に都度対応するでもいいんだけど、ライブラリ側の問題な気も。

その他requiredContextやrequiredActivityでの not attached to activity も多い。 事前にLifecycle.Stateをチェックしないといけないんじゃnullチェックしてた頃とあんまり変わらなくなっちゃうな。

原因と対応

特定の更新系のAPI呼び出しをFragmentの lifecycleScope.launch で起動していたのが主な原因だったようだ。 lifecycleScope.launchだとFragmentのライフサイクルスコープになるため、Fragment自体がdestroyされるまでライフサイクルが終わらない。 そこで、スコープを viewLifecycleOwner.lifecycleScope.launch に変更することで、destroyViewが呼ばれるまでをライフサイクルとして 処理することでエラーが解消されるはず。