Posted at

Android Architecture Component - Handling Lifecycles

More than 1 year has passed since last update.

この記事は

「DeNA IPプラットフォーム事業部 Advent Calendar 2017」

5日目の穴埋め記事です。


はじめに

先日Googleさんで開催されたAndroid Architecture Component - Handling Lifecyclesの課題の実装部分を個人メモ程度にまとめます。

あんざいゆきさんによるスライド

appcompat-v7:26.1.0以降の環境が必要です。


課題1 - Lifecycleのcurrent stateを出力する。

onCreate等のライフサイクルメソッド内でLifecycleオブジェクトを取得してcurrentStateを出力するだけ。

override fun onResume() {

super.onResume()

android.util.Log.d("AAC", lifecycle.currentState)
}


課題2 - LifecycleObserverを利用して各ステートを出力する。

LifecycleObserverを継承して適当なメソッドに@OnLifecycleEventのアノテーションを付けることで、指定したイベントのコールバックを受け取ることができます。

onCreateのコールバックを受けるには以下のようにします。再度言うとメソッド名はなんでも構いません。

@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)

fun ON_CREATE(source: LifecycleOwner) {
android.util.Log.d("AAC", "Lifecycle.Event.ON_CREATE")
}

実装したLifecycleObserverをLifecycleオブジェクトに登録します。

lifecycle.addObserver(MyLifecycleObserver())

アノテーションに渡せる値にはLifecycle.Event.ON_CREATE、ON_START、ON_RESUME、ON_PAUSE、ON_STOP、ON_DESTROY、ON_ANYを利用することが出来ます。@OnLifecycleEventでアノテートしたメソッドはそれぞれLifecycleOwnerを引数として受け取ることができ、ON_ANYのみ追加でどのイベントが発生したかを判別するためのLifecycle.Eventを受け取ることができます。

@OnLifecycleEvent(Lifecycle.Event.ON_ANY)

fun ON_ANY(source: LifecycleOwner, event: Lifecycle.Event) {
android.util.Log.d("AAC", "Lifecycle.Event.ON_ANY(${event.name})")
}


課題3 - GenericLifecycleObserverを使って課題2をやる。

onStateChangedを実装してログを出力するだけ。

class MainActivity : AppCompatActivity(), GenericLifecycleObserver {

init {
lifecycle.addObserver(this)
}

...

override fun onStateChanged(source: LifecycleOwner?, event: Lifecycle.Event?) {
android.util.Log.d("AAC", event?.name)
}
}

GenericLifecycleObserverの利用は将来的にできなくなるかも知れません。LifecycleObserverを自分で実装しましょう。


課題4 - ProcessLifecycleOwnerを使ってアプリのライフサイクルイベントを出力する。

ProcessLifecycleOwnerの利用には下をbuild.gradleに追加します。

implementation "android.arch.lifecycle:extensions:1.0.0"

ApplicationクラスでProcessLifecycleOwner#onStateChangedを実装してログを出力するだけ。

class App : Application(), GenericLifecycleObserver {

override fun onCreate() {
super.onCreate()

ProcessLifecycleOwner.get().lifecycle.addObserver(this)
}
...

override fun onStateChanged(source: LifecycleOwner?, event: Lifecycle.Event?) {
android.util.Log.d("AAC", event?.name)
}
}


課題5 - 非同期処理の後にステートがonStart以降だったらUIを更新する。

非同期処理が終わったらisAtLeastメソッドを使ってチェックするだけ。

if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {

// update UI
}


課題6 - ボタンタップでJobIntentServiceをスタートして、onDestroy時にアプリがフォアグラウンドなら新しいアクティビティを開いて、バックグランドならトーストをだす。

課題5とほぼ同じ。JobIntentServiceを実装したサービスのonDestroyで、ProcessLifecycleOwnerから取得したLifecycleに対してSTARTEDかどうかをチェックして、trueならフォアグラウンド、falseならバックグラウンド。

if (ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {

// start activity
} else {
// toast
}

Manifestにサービス登録も必要です。

<service

android:name=".MyJobIntentService"
android:permission="android.permission.BIND_JOB_SERVICE" />


課題7

課題7は以前はアクティビティのライフサイクルメソッドに書いていた処理を、AACのLifecycleを使えばまとめられるよって例なので割愛します。


終わりに

アクティビティやアプリケーションのライフサイクルに依存した処理が必要な時に綺麗に書くことができそうです。

さっと書いた+コードも直書きのところがあるので間違いがあるかもです。