最近自分の勘違いに気づき、結構ビックリしてしまったのでブログに残しておく。
お馴染みの Activity
の getIntent()
。
画面遷移時にデータの受け渡しとかに使いますよね。
(もはやSingle Activityが普通なので使う機会はほとんど無いかもしれないが。)
developer.android.com
何を勘違いしていたかというと、Activity
がシステムに破棄されて再生成された場合に getIntent()
は null
になり使えなくなるということ。
Androidだとシステムによって破棄されて〜、みたいなのはあるあるな話で、それを想定してコードを書くのが普通。
では getIntent()
が null
になるんだよなぁと思っていた場合にシステムの破棄にどうやって対応していたかというと、コードとしては下記のような感じ。
(Kotlinなので getIntent()
は intent
になっている。)( id
は参照するだけで値を変えたりはしない想定)
private val key = "key_id" private var id = 0 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) if (savedInstanceState == null) { this.id = intent.getIntExtra(key, 0) // 1 } else { this.id = savedInstanceState.getInt(key) // 3 } } override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putInt(key, id) // 2 }
- まず最初に
intent
から値を取り出して、インスタンス変数に入れる。 - そして、破棄に備え
onSaveInstanceState
でインスタンス変数の値を保持するように指定。 - 破棄されて再生成された場合、
onCreate
のsavedInstanceState
に保持した値が入ってくるので、それを取り出して使うようにする。
みたいな感じ。
まずインスタンス変数を1つ定義するのが面倒だし、 onSaveInstanceState
の処理も無駄ではあるのですが、勘違いしていたのでしょうがなくこの冗長なコードを書かなくてはいけないと思っていたのでした…
一応実機で確認したり、ネットで検索しても「再生成されても getIntent()
は元の値を返すよ」的なこと言っているのを発見したりしたので確信に変わったのでした。(ChatGPTはなんか曖昧な返答だったので参考にはならなかった。)
https://stackoverflow.com/questions/12111448/if-an-activity-is-stopped-then-recreated-what-gets-passed-into-getintent/30666666#30666666
いつからこの勘違いをしていたのかなぁと思ってハードディスクに眠っている個人の古いコードを見てみても、該当のコードは見つけられず。(そもそも破棄を想定してコードを書いてなかった可能性のほうが高いけども…。)
ただ本当にもう当然・絶対と思っていたことだったので、「まさか違うのか…?!」とわかった時はだいぶ驚きました。
こういう勘違いはほかにもあると思うので、学び直しって重要だよなと思ったのでした。