androidx では startActivityForResylt から Activity Result API を

はじめに

androidx では、startActivityForResult を非推奨に Activity Result API を強く推奨するというので使ってみた
旧形式でも今のところ問題なく使えて非推奨にしているだけなので使い勝手が良い方を選択すれば良い

旧形式定義例

ID を定義して、出口が onActivityResult イベントハンドラなり、それぞれが離れ離れでまとめて管理できないのが歯がゆい
それでも特に隠れた制限もなく使いやすかった

    private val ID_ACTIVITY = 1000

    override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
        super.onActivityResult(requestCode, resultCode, intent)
        if (requestCode == ID_ACTIVITY) {
            if (resultCode == Activity.RESULT_OK) {
                // 何らかの処理
            }
        }
    }

        startActivityForResult(Intent(this, SettingsActivity::class.java), ID_ACTIVITY)

新形式定義例

API呼び出しを変数定義して呼び出すシンプルで使いやすい

    private val launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
        if (result.resultCode == Activity.RESULT_OK) {
            // 何らかの処理
        }
    }

        launcherSettings.launch(Intent(this, SettingsActivity::class.java))

しかし、次のような隠れ制約もあり!旧形式とどっちが良いとも思えない

定義と呼び出しを一括定義できない

呼び出しタイミングの関数内に、定義と呼び出しを記述しても呼び出しに失敗する

    val launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    }
    launcherSettings.launch(Intent(this, SettingsActivity::class.java))

上記を実行すると呼び出しタイミングで例外が発生する

FATAL EXCEPTION: main
java.lang.IllegalStateException: LifecycleOwner trikstra.android.choutango.MainActivity@42145cf is attempting to register while current state is RESUMED. LifecycleOwners must call register before they are STARTED.

メッセージ通りに Activity の LifeCycle で STARTED までに register を呼び出す必要がある
この制限が自分には使い勝手が悪く感じる(一連の処理はできるだけ一箇所にまとまってほしい)
Activity のメンバ変数として register を定義するのが一番わかりやすい

Activity Result API を使うには

必要か不明だが API 定義が解決できないなら参照ライブラリを追加する

build.gradle

implementation 'androidx.activity:activity-ktx:1.7.2'

まとめ

それぞれに良い/悪いがあるので使いやすい方を選択していくのも良い
それと、register / startActivityForResut ともに外部アプリIntent呼び出しするアプリの終了復帰を待たずに呼び出し直後に Result 処理が呼び出される問題が見つかる

タイトルとURLをコピーしました