[解決済み] Kotlinコルーチンへの既存の3機能コールバック
2023-04-28 19:29:17
質問
一般的な質問と具体的な例を挙げます。 Androidで写真を撮るときに、コールバック地獄の代わりにKotlinのコルーチンマジックを使いたいと思っています。
manager.openCamera(cameraId, object : CameraDevice.StateCallback() {
override fun onOpened(openedCameraDevice: CameraDevice) {
println("Camera onOpened")
// even more callbacks with openedCameraDevice.createCaptureRequest()....
}
override fun onDisconnected(cameraDevice: CameraDevice) {
println("Camera onDisconnected")
cameraDevice.close()
}
...
どうすれば醜くないものに変換できるのでしょうか? 3つくらいの関数からなる平均的なコールバックを、主フローをプロミス結果のパスとして指定することでプロミスチェーンにすることは可能でしょうか? そして、もしそうなら、私はそれを非同期にするためにコルーチンを使うべきですか/そうですか?
asyncと.awaitで、結果的に何か欲しいです。
manager.open(cameraId).await().createCaptureRequest()
のようなものを使ってやろうとしているのですが、その際に
CompletableDeferred
を正しく使えていないようです!
suspend fun CameraManager.open(cameraId:String): CameraDevice {
val response = CompletableDeferred<CameraDevice>()
this.openCamera(cameraId, object : CameraDevice.StateCallback() {
override fun onOpened(cameraDevice: CameraDevice) {
println("camera onOpened $cameraDevice")
response.complete(cameraDevice)
}
override fun onDisconnected(cameraDevice: CameraDevice) {
response.completeExceptionally(Exception("Camera onDisconnected $cameraDevice"))
cameraDevice.close()
}
override fun onError(cameraDevice: CameraDevice, error: Int) {
response.completeExceptionally(Exception("Camera onError $cameraDevice $error"))
cameraDevice.close()
}
}, Handler())
return response.await()
}
どのように解決するのですか?
この特定のケースでは、コールバックベースの API をサスペンド関数に変換する一般的なアプローチを使用することができます。
suspendCoroutine
関数を使用します。
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) {
// assuming that we don't care about the error in this example
cont.resume(null)
}
}
openCamera(cameraId, callback, null)
}
さて、アプリケーションのコードでは、単に
manager.openCamera(cameraId)
への参照を取得し
CameraDevice
への参照を取得し、それが正常に開かれた場合は
null
となります。
関連
-
[解決済み] Kotlin 三項条件演算子
-
[解決済み】KotlinでJavaの静的メソッドに相当するものは何ですか?
-
[解決済み】Kotlinのコルーチンにおけるlaunch/joinとasync/awaitの違いとは?
-
[解決済み] HttpPostによる画像送信
-
[解決済み] CardView layout_width="match_parent "が親のRecyclerViewの幅と一致しない。
-
[解決済み] ViewPagerのアイテムを強制的に再インスタンス化する方法 [重複].
-
[解決済み] ProjectScopeServices に Factory タイプのサービスはありません。
-
[解決済み] Android Lintが翻訳されていない文字列を訴えないようにする。
-
[解決済み] サポートライブラリのアクションバーをPreferenceActivityに追加するには?
-
[解決済み] 実行に失敗しました app:processDebugResources Android Studio
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] BottomSheetDialogFragmentの状態をexpandedに設定する。
-
[解決済み] Androidでマイナスマージンを使用するのは悪いことですか?
-
[解決済み] 複数のフィルタを持つBroadcastReceiverか、複数のBroadcastReceiverか?
-
[解決済み] react nativeアプリのバージョン番号を更新する方法
-
[解決済み] FragmentPagerAdapterのgetItemが呼び出されない
-
[解決済み] Android Lintが翻訳されていない文字列を訴えないようにする。
-
[解決済み] google-services.jsonって実際何してるの?
-
[解決済み] Android: xml リソースからの整数値
-
[解決済み] 実行に失敗しました app:processDebugResources Android Studio
-
[解決済み] WhatsAppでメッセージを送信する