0

バックグラウンド

UI (アプリ)、ドメイン、およびデータベース (ルーム) を個別のモジュールとして、六角形のアーキテクチャとしてアプリをセットアップしています。UI のボタンを押すと、ユーザー入力データがルーム データベースに保存されます。Room データベースがSQLiteConstraintExceptionキーが DB に既に存在するという意味をスローする場合、データを上書きするかどうかをユーザーに問い合わせたいと思います。

私のアイデア

私はアンドロイド/コトリン開発に不慣れですが、これがどのように機能すると想像するかは、UIアラートダイアログをトリガーするイベントがあることです。DB モジュールでこのイベントを発生させ、アラート ダイアログが受け入れられた場合、コールバックが Room DAO で save メソッドを実行し、データを上書きします。

問題点

  • Kotlin のイベントに関するドキュメントをいくつか見つけようとしましたが、何もありませんでした。正しい用語を使用していない可能性がありますが、「イベント」は Kotlin では認識されていないようです。
  • DB モジュールは UI モジュールを認識しないため、ダイアログを DB から直接作成することはできません。これが、そもそもイベントを使用したい理由です。
  • Room は非同期であるため、保存メソッドをDispatchers.IOコルーチンで実行しています。私の知る限り、IO コルーチンで UI フラグメント (ダイアログなど) を作成することはできません。これまでのところ、使用してこの問題を回避してきましthis@MyActivity.runOnUiThreadたが、それは非常にハッキリしています。

私が試したこと

        GlobalScope.launch(Dispatchers.IO) {
            val result = data.save(force = false)
            when (result) {
                false -> {
                    this@DataSaverActivity.runOnUiThread {
                        GenericDialogs(this@DataSaverActivity)
                            .confirmDialog(
                                onAccept = {data.save(force = true)},
                                onReject = {println("dialog rejected")})
                    }
                }
                true -> println("Successfully saved")
            }
        }

それで、最初の試みの私のハックジョブはうまくいきますが、まったく満足していませんこのコードは、保存ボタンが押されたときに呼び出されるビューモデルのメソッドにあります。 data.save()Dao が a を上げる場合は false を返し、それ以外の場合はSQLiteConstraintExceptiontrue を返します。引数は、またはforceを使用してデータを保存するかどうかを決定します。基本的に true の場合は既存のキーを上書きし、false の場合は SQL エラーをスローします。保存に失敗すると、ダイアログが作成され、強制的に上書きして再保存するコールバックが提供されます。onConflict = ABORTonClonflict = REPLACEforce

ロジックをクリーンアップするために、Kotlin でイベントまたは同等のものを使用することをお勧めします。

4

1 に答える 1