Android 12ではMaterial Youが採用されたり、スクロールのエフェクトが変わったり、スプラッシュ画面がついたりと、UI周りの変更が多く見られました。
その裏で、セキュリティやパフォーマンス等に関する内部的な変更もいくつか存在します。
今回はその中から、ActivityのLifecycleに一部変更があった点について紹介を行い、また開発者が気をつけるべき点について解説します。
Android 12から、ルートのActivityを表示しているとき、戻るボタンを押してホーム画面に戻ったときの挙動が変わりました (詳細)。
Android 11以前では、ActivityがDestroyされており、再度起動したときは初期化されonCreateから呼ばれていました。
確認のため、以下のようなActivityでログを見てみます。
class LifecycleLogObserver : LifecycleEventObserver {
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
Log.d(source::class.java.simpleName, event.name)
}
}
class SampleActivity: AppCompatActivity() {
init {
lifecycle.addObserver(LifecycleLogObserver())
}
}
Activityを起動し、一度戻るボタンで終了した後に再度開いてみます。
// 初回起動
D/SampleActivity: ON_CREATE
D/SampleActivity: ON_START
D/SampleActivity: ON_RESUME
// 戻るボタン
D/SampleActivity: ON_PAUSE
D/SampleActivity: ON_STOP
D/SampleActivity: ON_DESTROY
// 再度起動
D/SampleActivity: ON_CREATE
D/SampleActivity: ON_START
D/SampleActivity: ON_RESUME
ViewModelも破棄され、 savedInstanceState
も保持されないためスクロール位置等もリセットされます。
次にAndroid 12の挙動です。onDestory
が呼ばれなくなり、再開時も onStart
から呼ばれています。
// 初回起動
D/SampleActivity: ON_CREATE
D/SampleActivity: ON_START
D/SampleActivity: ON_RESUME
// 戻るボタン
D/SampleActivity: ON_PAUSE
D/SampleActivity: ON_STOP
// 再度起動
D/SampleActivity: ON_START
D/SampleActivity: ON_RESUME
ViewModelも破棄されていないので、全ての状態はそのまま再開されます。
これは、ホームボタンを押してホームに戻ったときと全く同じLifecycleとなります。
ちなみに、ここでいうルートのActivityとは、 ACTION_MAIN
と CATEGORY_LAUNCHER
が指定されているactivityのことで、通知やWidget、deep link等によって起動したルート以外のActivityは引き続き戻るボタンでDestroyされます。
この変更により、ほとんどの場合、ユーザーはスムーズにアプリケーションの使用を再開できます。
ほとんどの場合、この変更によって問題になることはないでしょう。
考慮する必要がある点として、onBackPressed
をoverrideしており、その中で finish
を呼んでいる場合に、android 12でもActivityが終了されてしまいます。
この場合は代わりに super.onBackPressed()
を呼ぶことで、他のアプリケーションと同じ挙動に合わせることが出来ます。
class SampleActivity : AppCompatActivity() {
private var flag = true
override fun onBackPressed() {
if (flag) {
flag = false
return
}
- finish()
+ super.onBackPressed()
}
}
現在では OnBackPressedCallback を使ったほうが容易に戻るボタンのハンドリングを行えるでしょう。
もう1点意識したほうが良いと思うのは、onStop
の状態になるケースが増えるということです。
LifecycleがアクティブでないときにUIの更新や不要な処理を抑制することにより、不要なリソースと電力を消費するのを防ぐことができます。
今回紹介した変更はそこまで大きな変更ではありませんが、ユーザにとっては便利に感じるタイミングもあるでしょう。
Lifecycleは複雑で難しいですが、正しく理解することでユーザのリソースを効率よく使うことが出来ます。
開発者はOSの方針を理解し、それに応じた実装をする必要があると考えています。