android - 为什么 Room 不创建数据库?
问题描述
我正在为我的项目使用房间,但我无法创建房间数据库。
你能告诉我我做错了什么吗?
谢谢!
我有一个名为Appointment
.
@Entity
public class Appointment {
@PrimaryKey
@NonNull
private final UUID uuid;
private String title;
private String description;
public Appointment(UUID uuid, String title, String description) {
this.uuid = uuid;
this.title = title;
this.description = description;
}
我已经实现了一个名为AppointmentDAO
:
@Dao
public interface AppointmentDAO {
@Transaction
@Query("SELECT * FROM Appointment")
public List<Appointment> getAppointments();
@Transaction
@Query("SELECT * FROM Appointment WHERE uuid = :uuid")
public List<Appointment> getAppointmentByUUID(UUID uuid);
@Insert
void insertAppointment(Appointment appointment);
@Update
void updateAppointment(Appointment appointment);
@Delete
void deleteAppointment(Appointment appointment);
@Query("SELECT * FROM Appointment")
Single<List<Appointment>> getAppointmentsAsyncOneShot();
@Query("SELECT * FROM Appointment WHERE uuid = :uuid")
Single<Appointment> getAppointmentByUUIDAsyncOneShot(UUID uuid);
@Insert
Completable insertAppointmentAsyncOneShot(Appointment appointment);
@Update
Completable updateAppointmentAsyncOneShot(Appointment appointment);
@Delete
Completable deleteAppointmentAsyncOneShot(Appointment appointment);
@Query("SELECT * FROM Appointment")
Flowable<Appointment> getAppointmentsAsyncObservable();
@Query("SELECT * FROM Appointment WHERE uuid = :uuid")
Flowable<Appointment> getAppointmentByUUIDAsyncObservable(UUID uuid);
}
我还创建了一个AppDatabase
抽象类:
@Database(entities = {
Appointment.class
}, version = 1)
@TypeConverters({
UUIDConverter.class
})
public abstract class AppDatabase extends RoomDatabase {
private static final String TAG = "AppDatabase";
private static final String DB_NAME = "XXXYYYYYYYYYYDatabase.db";
private static AppDatabase instance;
protected AppDatabase() {}
public static synchronized AppDatabase getInstance(Context context) {
if (instance == null) {
instance = create(context);
}
return instance;
}
private static AppDatabase create(final Context context) {
Log.d(TAG, "create() called with: context = [" + context + "]");
return Room
.databaseBuilder(context.getApplicationContext(), AppDatabase.class, DB_NAME)
.build();
}
public abstract AppointmentDAO getAppointmentDAO();
}
我在一个片段中调用这个方法,它异步插入一个Appointment
:
private void addAppointmentToDatabase() {
AppDatabase
.getInstance(requireContext())
.getAppointmentDAO()
.insertAppointmentAsyncOneShot(viewModel.getAppointment().getValue())
.subscribe(new DisposableCompletableObserver() {
@Override
public void onComplete() {
Toast.makeText(requireContext(), "YES", Toast.LENGTH_LONG)
.show();
}
@Override
public void onError(@NonNull Throwable e) {
Toast.makeText(requireContext(), "NO", Toast.LENGTH_LONG)
.show();
}
});
}
build.gradle(应用程序):
plugins {
id 'com.android.application'
}
android {
compileSdkVersion 29
buildToolsVersion "30.0.2"
defaultConfig {
applicationId "com.example.xxxxxxxx"
minSdkVersion 22
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
}
buildFeatures {
dataBinding true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.google.android.gms:play-services-maps:17.0.0'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
testImplementation 'junit:junit:4.13.1'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
def nav_version = "2.3.2"
// Java language implementation
implementation "androidx.navigation:navigation-fragment:$nav_version"
implementation "androidx.navigation:navigation-ui:$nav_version"
// Feature module Support
implementation "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"
// Testing Navigation
androidTestImplementation "androidx.navigation:navigation-testing:$nav_version"
// Jetpack Compose Integration
implementation "androidx.navigation:navigation-compose:1.0.0-alpha04"
implementation 'com.google.android.gms:play-services-location:17.1.0'
def room_version = "2.2.6"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
// optional - RxJava support for Room
implementation "androidx.room:room-rxjava2:$room_version"
// optional - Guava support for Room, including Optional and ListenableFuture
implementation "androidx.room:room-guava:$room_version"
// optional - Test helpers
testImplementation "androidx.room:room-testing:$room_version"
}
我没有错误,也没有数据库:(。
解决方案
啊 - 你没有正确使用 rxJava。简单明了,您不能在主 UI 线程上进行数据库调用。Room 要求在单独的线程中调用它们。rxJava 增加了一定程度的复杂性,使得一开始很难调试。我建议使用 Runnable 或 Executors 类创建一个非常简单的线程,并在其中调用 db 函数。一旦您可以确认您的数据库逻辑正在工作,那么您可以继续实现 rxJava。
编辑:我不是 rxJava 的专业人士,但我确实相信您缺少设置要在哪个线程上运行的功能(AndroidSchedulers.io)或类似的东西,我不记得了。
可运行的示例:
private void addAppointmentToDatabase(Appointment appointment) {
new Runnable() {
@Override
public void run() {
AppDatabase
.getInstance(requireContext())
.getAppointmentDAO()
.insertAppointment(appointment);
}
};
}
推荐阅读
- c++ - 尝试在 mac [C++] 上使用 system() 打开应用程序时出现问题
- asp.net-mvc - 如何使用 MediatR 为同一请求模型获取不同的响应类型?
- python - (Discord.py) 我如何制作一个敢于 21 的游戏?我需要以数字的形式输入,比如“1 2 3”(最多 3 个数字)并轮流输入?
- android - 合并错误:android studio中的任务名称键属性
- python - 为什么我的代码无法使用 python 和 SQL 服务器将字符串转换为字节
- r - 将 `c(x, y)` 作为函数参数转换为 R 中的 `c("x", "y")` (rlang/tidyevaluation)
- microsoft-teams - MSTeams 配置页面 Angular 12 SPA 与路由
- python - 从标记化数组中删除奇怪的字符
- ghostscript - 是否有其他图像文件格式快速且可用作类似于 MIFF 文件的转换的中间文件?
- jquery - jquery 插件“缩短”规范不会随“window.width()”而改变