エミュレータでカメラ起動すると映るコレ。
微妙に動いてるんですけど...
何かのキャラなのか、
家にも見えたりするだけども、動いてるし。
一体、何なのっ?!
なんだか微妙な感じします。
APIの仕様がなのか、
サンプルのコードがなのか、
Camera2。
android-Camera2Basic/Camera2BasicFragment.kt at master · googlesamples/android-Camera2Basic
いくつかのコールバック処理が
連続して処理されますが
kotlin の芸当で分かりやすくしてみましょう。
多くの非同期処理APIは
コールバックスタイルのインターフェースを持ってます。
suspendCoroutine の 「suspend function」 を使うと
簡単にコールバックをその中にラッピングすることができます。
簡単な例を挙げてみます。
fun longComputation(params: Params, callback: (Result) -> Unit)
longComputation という function があって、
それのコールバックは Result という計算結果を受け取ります。
これは、以下のように簡単にラッピングできます。
suspend fun longComputation(params: Params): Result = suspendCoroutine { cont ->
longComputation(params) { cont.resume(it) }
}
分かりやすく計算結果を返し、同じ非同期ですがスレッドをブロックしません。
kotlin-coroutines/kotlin-coroutines-informal.md at master · Kotlin/kotlin-coroutines
例えば、Camera2 APIでは必須のこれ。
void openCamera (String cameraId,
CameraDevice.StateCallback callback,
Handler handler)
CameraManager | Android Developers
コールバックとバックグラウンドハンドラやスレッドの
準備や後始末の処理が必要ですが、
それらがあちこちに分散してしまい辛くなりますが、
Kotlin coroutine に頼ると、
きれいにラッピングできます。
suspend fun CameraManager.openCamera(cameraId: String): CameraDevice? =
suspendCoroutine { cont ->
val callback = object : CameraDevice.StateCallback() {
override fun onOpened(camera: CameraDevice) {
cont.resume(camera)
}
override fun onDisconnected(camera: CameraDevice) {
cont.resume(null)
}
override fun onError(camera: CameraDevice, error: Int) {
cont.resume(null)
}
}
openCamera(cameraId, callback, null)
}
android - Existing 3-function callback to Kotlin Coroutines - Stack Overflow
他のいくつかのコールバックも
同じように書き換えていくと
かなり見通しよくなります。
しかし、
このGサンプルコードは分かりづらすぎぢゃんね?