[英]Why Room doesn't create database?
I'm using a Room for my project but I can't create a Room Database.我正在为我的项目使用房间,但我无法创建房间数据库。
Could you please, tell me what I am doing wrong?你能告诉我我做错了什么吗?
Thanks!谢谢!
I have one entity called Appointment
.我有一个名为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;
}
I've implemented a DAO called AppointmentDAO
:我已经实现了一个名为AppointmentDAO
的 DAO:
@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);
}
I also created a AppDatabase
abstract class:我还创建了一个AppDatabase
抽象 class:
@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();
}
I'm calling in a fragment this method which inserts asynchronously an Appointment
:我在一个片段中调用这个方法,它异步插入一个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 (app): 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"
}
I've got no errors and no database:(.我没有错误,也没有数据库:(。
Ah - you aren't properly using rxJava.啊 - 你没有正确使用 rxJava。 Plain and simple, you can't make Database calls on the main UI thread.简单明了,您不能在主 UI 线程上进行数据库调用。 Room demands that they are called in a separate thread. Room 要求在单独的线程中调用它们。 rxJava adds a level of complexity that can make it hard to debug in the beginning. rxJava 增加了一定程度的复杂性,使得一开始很难调试。 I suggest making a very simple thread with Runnable or Executors class, and call the db function inside that.我建议使用 Runnable 或 Executors class 创建一个非常简单的线程,并在其中调用 db function。 Once you can confirm that your db logic is working, then you can proceed implementing rxJava.一旦您可以确认您的数据库逻辑正在工作,那么您可以继续实现 rxJava。
edit: I'm not a pro at rxJava, but I do believe you are missing the function to set which thread to run on (AndroidSchedulers.io) or something like that, I can't remember off the top of my head.编辑:我不是 rxJava 的专业人士,但我相信你错过了 function 来设置要在哪个线程上运行(AndroidSchedulers.io)或类似的东西,我不记得了。
Example of a Runnable:可运行的示例:
private void addAppointmentToDatabase(Appointment appointment) {
new Runnable() {
@Override
public void run() {
AppDatabase
.getInstance(requireContext())
.getAppointmentDAO()
.insertAppointment(appointment);
}
};
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.