こんにちは!
2024 年新卒入社、アプリ開発支援部の涌井です。
アプリ開発支援部の一員として、Android の開発研修が一通り完了したため、その際に詰まった内容をまとめる第 1 弾です。
今回は、Activity の画面遷移やライフサイクルについてまとめます。
Android 開発研修の概要については以下なので、ぜひ確認いただけると嬉しいです。
【24 卒新卒エンジニア】研修の振り返り!モバイルアプリのエンジニア研修ではどんなことやったのか? - エムティーアイ エンジニアリングブログ
※この記事は、アドベントカレンダー12月3日分の記事です。 qiita.com
目次
Android での画面遷移方法の振り返り
今まで私は、onCreate
内で以下のように、startActivity
を用いて画面遷移していました。
単純な画面遷移のときも「戻る」動作のときも、startActivity
を使っていました。
val intent = Intent(this, HogeActivity::class.java) startActivity(intent)
しかし、研修の課題内での、「エラー画面遷移後、戻ったときに再度取得処理が走るように」という以下のような図の動作をしたいときに、つまずいてしまいました。
実際に実装した時に、どういう動作をしてしまったかというと、「戻る」を押した後に、取得処理がされるべきところが、空白が表示された状態で戻ってしまうという動作をしたのです。
これは、理想としている動作ではありません。
なぜつまずいたのか?
理由として、2 点あります。
1 つ目は、finish()
ではなく、startActivity()
を使って画面遷移してしまったからです。
以下のように、Android のstartActivity()
では、上に重なるような動作をするので、うまくいっていなかったということです。
Web での画面遷移とは違い、「遷移」というよりも「積み込む」ような挙動をしている。
例えるならば、紙芝居のようなもの。
Activity のライフサイクルについて #Android - Qiitaより引用
finisth()
の動作は、Activity を消す、みたいなイメージなので、startActivity()
のように積み重ねず、元々の MainActivity を再度表示することができます。
2 つ目は、Acitivity のライフサイクルを生かさず、activityResultLauncher
を使っていたということです。
もちろん、activityResultLauncher
を使っても、「エラー画面遷移後、戻ったときに再度取得処理が走るように」という動作は達成できます。
しかし、Activity のライフサイクルを生かす方がスマートに実現できますし、Android では必ず知識として覚えておくべきものなので、Activity のライフサイクルに変更しました。
ライフサイクルの解説
状態が変わると、ライフサイクルが走ります。
- 何らかの動作によって、アクティビティが一時停止
- 端末の向きかわるなど
onCreate
,onStart
,onResume
は、起動時絶対に走ります。
ライフサイクルの動作の図解は以下です。
ActivityRunning
→Activity を表示している状態のことを指します。onCreate()
アクティビティの開始時に呼び出されます。
Activity #onCreate() | Android Developersより翻訳して引用onStart()
onCreate(Bundle)
の後、またはアクティビティが停止したが、再びユーザーに表示されるようになったときに、onRestart()
の後に呼び出されます。通常はonResume()
が続きます。
Activity #onStart() | Android Developersより翻訳して引用onRestart()
現在のアクティビティがユーザーに再表示される(ユーザーがナビゲートして戻った)ときに、
onStop()
の後に呼び出されます。onStart()
、onResume()
と続きます。
Activity | Android Developersより翻訳して引用onResume()
onRestoreInstanceState(Bundle)
、onRestart()
、またはonPause()
の後に呼び出されます。
Activity #onResume() | Android Developersより翻訳して引用onPause()
、onStop()
→ 上にアクティビティが被さっている時や一時ストップしているときのことを指します。
上に別のアクティビティがある時、onPause()
かonStop()
まで走ります。
少なくともonPause()
まで呼ばれますが、場合によってはonStop()
まで呼ばれることもあります。
Log を仕込んだりして確認すると良いと思います。onPause()
ユーザーがアクティビティとアクティブに相互作用しなくなったが、画面上にはまだ表示されている場合に、アクティビティライフサイクルの一部として呼び出される。
onResume()
と対になるものです。
Activity #onPause() | Android Developersより翻訳して引用onStop()
ユーザーから見えなくなったときに呼び出されます。次に、
onRestart()
、onDestroy()
のいずれかを受け取るか、あるいは何も受け取らないか、後のユーザーの活動に応じて決まります。
Activity #onStop() | Android Developersより翻訳して引用
onDestroy()
Activity が消え去る時に走ります。アクティビティが破棄される前に、最終的なクリーンアップを行う。これは、アクティビティが終了する (誰かがそのアクティビティで
finish()
をコールした) か、あるいはシステムがスペースを節約するためにアクティビティのインスタンスを一時的に破棄するかのどちらかです。
Activity #onDestroy() | Android Developersより翻訳して引用
アクティビティの遷移
Activity から Activity の遷移時、終了させたい時は、以下のようすると良いです。
val intent = Intent(applicationContext, SubActivity::class.java) startActivity(intent) finish()
【Android】画面遷移時に遷移元の Activity を終了する #Java - Qiitaのコードを、Java から Kotlin に変更して引用。
今回はどのように実装したか?
「エラー画面遷移後、戻ったときに再度取得処理が走るように」という動作を、ライフサイクルをうまく利用してどのように実装したかをまとめます。
1. finish()
を使って、アクティビティを終了させる。
あるアクティビティの onCreate 内にて、以下のように実装しました。
(ボタンを押したら、finish()
が走り、アクティビティが終了します。
val button = findViewById<Button>(R.id.button)
button.setOnClickListener {
finish()
}
2. onResume
を使用して、再度取得処理を行ないます。
override fun onResume() {
super.onResume()
//メソッドを呼び出す
hogehogeData()
}
参考記事
本記事は、以下の記事の内容を参考にしております。
終わりに
ここまで読んでいただき、ありがとうございました。
今まで、Android をハッカソンなどで使用したことがあったのですが、その際は、ハッカソンで使えれば良い=動けば良いと言った感じで開発をしていたため、「ライフサイクル」について勉強する機会がありませんでした。
今回、身につけることができて、とても良かったです。
今後も、Android 開発研修などで学んだことを公開する予定なので、ぜひ見ていただきたいと思います。
ライセンスに関する特記事項
- 公式のライフサイクルの動作の図解の画像を使用し、文章を日本語訳にする変更を加えています。
Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License. - ライフサイクルの解説の引用部分の文章は、 Apache 2.0ライセンスで公開されている文章が含まれています。 具体的には、もとの文章を日本語訳しています。