こんにちは!Sansan事業部 プロダクト開発部のふるしんです。
私は大阪のオフィスでSansanプロダクトのAndroidアプリの開発に従事しています。
2020/04/29にActivityのVersion 1.2.0-alpha04が公開され、
startActivityForResult()とonActivityResult()、そしてonRequestPermissionsResult() がDeprecatedになったよ! 代わりにActivity Result APIsを使ってね!
とアナウンスがありました。
そこでこの記事では、startActivityForResult()とonActivityResult()を具体的にどのようにActivity Result API
を使って置き換えるのかを解説します。
startActivityForResultはAPI level 1
から存在するので、影響する方が非常に多いのではないかと想像します。
従来どおりに実装した場合
今まで通り実装したらこんな感じのイメージになります。
かなり省略してしまいましたが以下のことをしています。
- 呼び出す側のActivityのButtonを押したら
startActivityForResult
でSubActivityへ遷移する - SubActivityでButtonを押したらIntentへvalueとして100をセットし、Activity.RESULT_OKとともにsetResultしてからfinish()する
- MainActivity側の
onActivityResult
で返ってきた値をチェックしてToastを表示
呼び出す側のActivity
MainActivity.kt
binding.navigationButton.setOnClickListener { startActivityForResult(SubActivity.createIntent(this), REQUEST_CODE) } // ... override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) when (resultCode) { Activity.RESULT_OK -> { data?.let { data -> val value = data.getIntExtra(SubActivity.KEY_VALUE, 0) Toast.makeText(this, "$value", Toast.LENGTH_LONG).show() } } } }
呼び出される(Resultを返す)側のActivity
SubActivity.kt
binding.finishButton.setOnClickListener { val intent = Intent().apply { putExtra(KEY_VALUE, 100) } setResult(Activity.RESULT_OK, intent) finish() }
Deprecated後はどうなる?
ここからが本題です。上記の流れをActivity Result API
を使って書き換えたらどうなるか試してみます。
詳しくは公式ドキュメントに記載されていますので、それに則って実装してみます。
build.gradleに追加
まずは必要なものをbuild.gradleに追加しましょう。
androidx.activity:activity-ktxは1.0.0からAppCompat1.1.0が必要になっていますので、AppCompatのバージョンが低い方はバージョンアップが必要となります。
build.gradle
implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.activity:activity-ktx:1.2.0-alpha04'
呼び出し側を変更
呼び出し側は次のように変化します。
MainActivity.kt
val startForResult = registerForActivityResult(StartActivityForResult()) { result: ActivityResult? -> if (result?.resultCode == Activity.RESULT_OK) { result.data?.let { data: Intent -> val value = data.getIntExtra(SubActivity.KEY_VALUE, 0) Toast.makeText(this, "$value", Toast.LENGTH_LONG).show() } } } startForResult.launch(SubActivity.createIntent(this))
簡単に言うと「onActivityResultの中身がregisterForActivityResultのラムダ式に入っちゃった!」という程度の変化です。
正直なところ大きな変化があったのではないかとビクビクしていましたが、とてもシンプルになった印象です!
呼び出される側は?
呼び出される側は何も変わりません!
まとめ
今回はstartActivityForResult()とonActivityResult()だけにフォーカスしましたが、他にもActivityResultContractを継承したカスタマイズもできるようになってるので、柔軟性が増えた印象です。
余談ですが、gradleにandroidx.activity:activity-ktx:1.2.0-alpha04
を追加したらDeprecatedだとstartActivityForResult
に線が引かれました。
わかっちゃいましたがすごい変化だなぁと感じています。
最後に
Sansanでは一緒に働く仲間を募集しています!
興味が湧きましたらぜひお声がけください!