非同期処理とFragment
なんか非同期処理してそれが終わったらFragmentを生成してFragmentManagerに追加するみたいな処理するときってあれですよね。
onSaveInstanceStateの後にやってしまうと怒られますよね。
それ回避用のユーティリティークラス作ってみたのでメモ書きです。
Android Architecture Componentsのlifecycleを使用します。
import android.arch.lifecycle.Lifecycle import android.arch.lifecycle.LifecycleObserver import android.arch.lifecycle.LifecycleOwner import android.arch.lifecycle.OnLifecycleEvent interface IOnActiveRunner { fun setOwner(owner: LifecycleOwner) fun runOnActive(handle: () -> Unit) } class OnActiveRunner : IOnActiveRunner { private val mObserver = OnActiveLifeCycleObserver() private var mIsOwnerInitialized = false override fun setOwner(owner: LifecycleOwner) { if (!mIsOwnerInitialized) owner.lifecycle.addObserver(mObserver) else throw IllegalStateException() mIsOwnerInitialized = true } override fun runOnActive(handle: () -> Unit) { if (!mIsOwnerInitialized) throw IllegalStateException() mObserver.run(handle) } class OnActiveLifeCycleObserver : LifecycleObserver { private var isSafe = true private val tasks = ArrayList<() -> Unit>() fun run(task: () -> Unit) { if (isSafe) { task() } else { tasks.add(task) } } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun onPause() { isSafe = false } @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun onResume() { isSafe = true tasks.forEach { it() } tasks.clear() } @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) fun onDestroy() { isSafe = false } } }
単純にonPause()が呼ばれたら与えられた関数オブジェクトをリザーブしてonResume()で実行するってだけです。
インターフェースを用意したのは移譲を使ってActivity等で楽に使えるようにするためです。
使うときは…
class HogeActivity : AppCompatActivity(), IOnActiveRunner by OnActiveRunner() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) //runOnActiveを呼ぶ前にsetOwnerしておく setOwner(this) //例としてkotlinのcroutine使います launch(UI) { //async/awaitつかったりとか runOnActive { //何かしらの処理 } } } }
みたいな感じで使います。
非同期処理のコールバックでonPause後に呼ばれたくないような処理を行なう時に使う感じです。
最たるものはFragmentTransaction周りの処理だと思います。
他にもonPause後に呼ばれたくないような処理っていくらでもあると思うので使い所は結構多いのでは。
いや、こんなの用意しなくてもそれできるぜって情報があれば教えていただければ幸いです。
commitAllowingStateLossは無しの方向で