简体   繁体   English

为什么 Room 不创建数据库?

[英]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);
        }
    };
}

About Android Threads 关于 Android 线程

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM