私は自分のプロジェクトの新しいアーキテクチャコンポーネントからルームデータベースを使用しています。 daoを介してデータを追加していますが、取得しようとしても取得できません。挿入が成功したかどうかを確認する方法を教えてください。以下は、問題を理解するのに役立つコードです。
データベースに追加し、デバッガーでチェックすると、このステートメントは正常に実行されました。
appContext.db.rallyDAO().addVehicleListItem(vehicle)
挿入後にこのステートメントでデータベースからnullを取得します。
val v = appContext.db.rallyDAO().getVehicleListItem(it.vehicleID)
RoomDatabase
@Database(entities = arrayOf(Rally::class, Route::class, CheckPoints::class, Vehicles::class, VehicleListItem::class), version = 1)
abstract class TSDRoom: RoomDatabase() {
public abstract fun rallyDAO():RallyDAO
}
内部DAO
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun addVehicleListItem(vehicleListItem:VehicleListItem)
@Query("select * from vehicles_submitted where vehicle_id LIKE :vehicleID")
fun getVehicleListItem(vehicleID:String):VehicleListItem
VehicleListItemエンティティ
@Entity(tableName = "vehicles_submitted",
foreignKeys = arrayOf(ForeignKey(entity = Rally::class,
parentColumns = arrayOf("rally_id"),
childColumns = arrayOf("rally_id"))))
class VehicleListItem {
@PrimaryKey
@ColumnInfo(name = "vehicle_id")
@SerializedName("vehicle_id")
var vehicleID : String = ""
@ColumnInfo(name = "driver_id")
@SerializedName("driver_id")
var driverID : String = ""
@ColumnInfo(name = "vehicle_name")
@SerializedName("vehicle_name")
var vehicleName : String = ""
@ColumnInfo(name = "driver_name")
@SerializedName("driver_name")
var driverName : String = ""
@ColumnInfo(name = "driver_email")
@SerializedName("driver_email")
var driverEmail : String = ""
@ColumnInfo(name = "rally_id")
@SerializedName("rally_id")
var rallyID: String = ""
@ColumnInfo(name = "is_passed")
@SerializedName("is_passed")
var isPassed = false
@ColumnInfo(name = "passing_time")
@SerializedName("passing_time")
var passingTime:String=""
}
問題はスレッドにありました。ルームでは、メインスレッドでデータベースクエリを実行できません。 insertメソッドの呼び出しはtry-catchブロック内にあり、例外を無視していました。私はそれを修正しました、そして、ここでそれが今どのように読むかです。
doAsync {
val addedID = appContext.db.rallyDAO().addVehicleListItem(vehicle)
Logger.d("vehicle_lsit_item","Inserted ID $addedID")
}
また、私は documentation をレビューしました。挿入メソッドはLong(挿入に渡されたリストの場合はLongのリスト)を返すことがあります。挿入の署名も変更しましたが、変更したコードは次のとおりです
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun addVehicleListItem(vehicleListItem:VehicleListItem):Long
追伸doAsync
に anko を使用しています
Stethoを使用して、chrome devツールでDBおよび共有設定ファイルを確認できます
それをテストする方法は複数あります。
「data/data/yourpackage/databases/yourdatabase.db」からデータベースファイルをローカルマシンにプルし、アプリケーションを使用してデータベース内のコンテンツを読み取ります。私は個人的に https://sqlitebrowser.org/ を使用しています。データベースファイルのプルは、シェルコマンドを使用するか、Android studio。
TestCaseを作成して、機能するかどうかを確認します。これが私のプロジェクトのテストケースの例です。
// DAOクラスのコード
@Insert(onConflict = OnConflictStrategy.REPLACE)public abstract Long [] insertPurchaseHistory(List MusicOrders);
// My Test Case @Test public void insertPurchaseHistoryTest(){
// Read test data from "api-responses/music-purchase-history-response.json"
InputStream inputStream = getClass().getClassLoader()
.getResourceAsStream("api-responses/music-purchase-history-response.json");
// Write utility method to convert your stream to a string.
String testData = FileManager.readFileFromStream(inputStream);
// Convert test data to "musicOrdersResponse"
MusicOrdersResponse musicOrdersResponse = new Gson().fromJson(testData,MusicOrdersResponse.class);
// Insert inmateMusicOrders and get the list of
Long[] rowsInserted = tracksDao.insertPurchaseHistory(musicOrdersResponse.getmusicOrders());
assertThat(rowsInserted.length,Matchers.greaterThan(0));
}
アクセス許可の問題がない場合に考慮できるオプションは、デバイスのsqliteインスタンスに直接移動し、そこでテーブルを直接クエリすることです。
Android Studioまたはルート化された電話と統合されたエミュレーターを使用する場合、次のことができます。
adb root
adb remount
cd data/data/path/of/your/application/database
sqlite3 mydb.db
その後、テーブルをクエリできます
Android Debug Database を使用して、Webブラウザー経由でアプリケーションのデータベースにアクセスできます。 Android Debug Databaseは、組み込みWebサーバーを介してデータベースを公開します。
次のように使用します。
アプリのbuild.gradle
にdebugImplementation
依存関係として含めて、リリースビルドではなくデバッグビルドにのみ含めるようにします。
debugImplementation 'com.amitshekhar.Android:debug-db:1.0.3'
アプリのデバッグビルドを開始する
組み込みWebサーバーが自動的に起動し、ログでアドレスとポートを通知します。
D/DebugDB: Open http://XXX.XXX.X.XXX:8080 in your browser
USB経由でアプリを実行している場合、ポートフォワーディングを設定します。
adb forward tcp:8080 tcp:8080
USB経由でアプリを実行していない場合、Android電話とワークステーションは同じネットワーク内にある必要があり、ワークステーションはAndroid電話。
最後に、ブラウザのログからリンクを開きます。
Webサーバーはアプリコンテキスト内で実行されるため、デバイスをルート化せずに正常に動作することに注意してください。