#startActivityForResultとonActivityResult
通常立ち上げたactivityから結果を受け取るには
requestCodeを定義し。startActivityForResultを呼び出し
onActivityResultをoverrideして結果を受け取ります。
機能が増えていくとrequestCodeの定義とonActivityResultの中の
実装が増えていき煩雑になっていきます。
#Coroutineを用いたonActivityResultの実装
本記事はcoroutineを用いてstartActivityForResultからonActivityResultまでの
処理をシンプルに実装する処理を紹介します。
###BaseActivityの実装
まず、親となるActivityにcoroutineを用いて
onActivityResultの待ち合わせ処理を実装します。
abstract class BaseActivity : AppCompatActivity() {
companion object {
private const val REQUEST_CODE_DEFERRED = 10001
}
//onActivityResultの結果待ち合わせ用
private var deferredResult = CompletableDeferred<ActivityResult>()
//startActivityForResult同時に待ち合わせ開始
fun launchStartActivityForResult(intent: Intent): Deferred<ActivityResult> {
if(deferredResult.isActive) deferredResult.cancel()
deferredResult = CompletableDeferred()
startActivityForResult(intent, REQUEST_CODE_DEFERRED)
return deferredResult
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if(requestCode == REQUEST_CODE_DEFERRED) {
//結果受け取り
deferredResult.complete(ActivityResult(resultCode, data))
} else {
super.onActivityResult(requestCode, resultCode, data)
}
}
}
class ActivityResult(val resultCode: Int, val data: Intent?) { }
deferredResultというCompletableDeferred型の待ち合わせオブジェクトを定義し、
launchStartActivityForResult関数で待ち合わせを始めて、
onActivityResultで結果を受け取ります。
###呼び出し側の例
上記で実装した関数を用いてカメラのIntentから結果を受け取るサンプル
button.setOnClickListener {
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
GlobalScope.launch(Dispatchers.Main) {
//startActivityForResultの結果の待ち合わせ
val activityResult = launchStartActivityForResult(intent).await()
if(activityResult.resultCode != Activity.RESULT_OK) return@launch
activityResult.data?.extras?.let { bundle ->
val bitmap = bundle.get("data") as Bitmap
//do something
}
}
}
BaseActiviyを継承したActivityで
coroutineスコープ内にてlaunchStartActivityForResult()を呼び
その返り値をawait()関数で待ちその後結果を処理します。
#まとめ
coroutineのスレッド待ち合わせを使うことによりstartActivityForResultからonActivityResultまでの処理をまとめて実装することができ、
requestCodeの定義も無くすことができました。