Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何认识那个房间';s onCreate()回调已结束_Java_Android_Android Room - Fatal编程技术网

Java 如何认识那个房间';s onCreate()回调已结束

Java 如何认识那个房间';s onCreate()回调已结束,java,android,android-room,Java,Android,Android Room,我正在开发一个使用Room数据库的应用程序;它是一个静态数据库,有3个表,我在应用程序第一次启动时通过在数据库实例化时覆盖onCreate()插入它们的数据 将所有静态记录插入三个表需要一段时间,因此我的应用程序无法访问数据库,直到onCreate()结束,才能获取正确的数据并显示给用户 当我尝试在活动的onCreate()方法中访问数据库时,它返回null数据,这实际上中断了文件室的onCreate操作,这导致即将启动的应用程序的空数据,因为文件室的onCreate()只调用一次 为了调试的目

我正在开发一个使用
Room
数据库的应用程序;它是一个静态数据库,有3个表,我在应用程序第一次启动时通过在数据库实例化时覆盖
onCreate()
插入它们的数据

将所有静态记录插入三个表需要一段时间,因此我的应用程序无法访问数据库,直到
onCreate()
结束,才能获取正确的数据并显示给用户


当我尝试在活动的
onCreate()
方法中访问数据库时,它返回
null
数据,这实际上中断了文件室的
onCreate
操作,这导致即将启动的应用程序的空数据,因为文件室的
onCreate()
只调用一次

为了调试的目的,当我摆脱这个数据库访问只为第一次启动的应用程序(清洁卸载后),以允许数据库建立为第一次启动;然后,当我将数据库查询重新添加到我的活动的
onCreate()
并重新启动应用程序时;返回非空数据;我只是想确保文件室的
onCreate()
在第一次发布后结束

我可以将侦听器传递到custom Room RoomDatabase类,在该类中,
onCreate()
方法结束时可以触发其回调;但我不确定这是正确的方法还是有另一种优雅的方法,这是正确的方法;然后,考虑到MVVM设计模式,比如
Repository
ViewModel
,如何以正确的方式实现它

下面是数据库类的外观

@Database(entities = {Table1.class, Table2.class, Table3.class}, version = 1, exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {

    public static final String DATABASE_NAME = "database.db";
    private static volatile AppDatabase INSTANCE;
    private static final Object LOCK = new Object();

    public abstract Table1Dao getTable1Dao();
    public abstract Table2Dao getTable2Dao();
    public abstract Table2Dao getTable3Dao();

    private static Executor mExecutor = Executors.newSingleThreadExecutor();


    static public AppDatabase getInstance(final Context context) {
        if (INSTANCE == null) {
            synchronized (LOCK) {
                if (INSTANCE == null) {
                    INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                            AppDatabase.class, DATABASE_NAME)
                            .addCallback(new Callback() {
                                @Override
                                public void onCreate(@NonNull SupportSQLiteDatabase db) {
                                    mExecutor.execute(() -> table1InsertOperation(context));
                                    mExecutor.execute(() -> table2InsertOperation(context));
                                    mExecutor.execute(() -> table3InsertOperation(context));
                                   super.onCreate(db);
                                }
                            })
                            .build();
                }
            }
        }
        return INSTANCE;
    }

}

感谢您的帮助

使用应用程序的开发版本或其他工具(例如)创建包含固定数据的数据库文件。将DB文件放在应用程序的
assets/
目录中,并使用它来创建数据库

有关详细信息,请参阅文档

用户认为,从返回后,生成的应用程序数据库将立即准备好使用。您也可以使用回调。

“当我尝试在activity的onCreate()方法中访问数据库时,它返回空数据,这实际上会中断文件室的onCreate操作,这会导致即将启动的应用程序的空数据,因为文件室的onCreate()只调用一次。” 这对我来说似乎很奇怪,db允许多个线程读写,那么为什么会发生这种情况呢

“我可以将侦听器传递给custom Room数据库类,在该类中,onCreate()方法结束时可以触发其回调”我看到您使用执行器在后台线程上运行填充阶段,因此onCreate应该几乎立即完成,填充db的线程很可能要晚很多。您必须监视您运行的三个线程何时全部完成工作。 与监听器相同,但更简单的是(一旦您解决了第1点,它似乎是代码中的某个地方的一个bug,或者不太可能是在房间中的bug),只需要有一个LiveData(或流)来告诉您何时插入所有行

看看这个回购协议: 她使用了一个
Executors.newSingleThreadExecutor()
,看起来与您的操作类似


安卓工作室4.1有一个惊人的数据库检查器,试试看

“静态数据库”是否意味着它是一个固定的只读资源?@Bob Snyder是的,没错Hi Andrew。。你是对的,但问题是我试图用一个查询访问数据库,而它仍在用回调函数构建初始数据。。。此访问会中断此回调的操作(在3个表中插入初始数据)。。。因此,当我再次启动应用程序时,它会在Room数据库中发现空数据,因为Room的OnCreate只能调用一次,而且只能调用一次,如文档所示。感谢您的回答和共享repoHi@Zain,对数据库的访问(读或写)不会中断同一数据库上的任何其他操作。您可以生成一百万个线程,并在这些线程中执行所有类型的操作(选择、插入、更新和删除)。数据库将始终保持一致。是的,例如,如果在一个线程中插入与已从另一个线程插入的行id相同的行,则可能会出现错误,并且该错误可能会停止事务的所有后续操作。但是,您需要在填充函数和其他访问上发布您所做的操作,以查看是否是这种情况。您说“这是一个静态数据库,有3个表,我第一次插入它们的数据”,因此我认为您应该在填充阶段执行所有插入操作,并且只在访问上选择,这应该不会出现问题。顺便问一下,为什么在onCreate上使用3个线程?3个线程给出的操作顺序的随机性是否会随机导致问题?我会使用一个线程(db很可能会将操作与他的线程池并行),我可以将三个插入放在一个线程中吗?让我试试看,根据线程执行其操作的时间,您可以获得不同的数据是正常的,为了让开发人员更容易思考,Room可以返回一个LiveData,这样您就可以观察该LiveData,并且当数据更改时,您的UI将被更新(在您的情况下,当插入完成时,如果之前运行了select)1.非常感谢鲍勃。。我将尝试这样做,希望它不会影响应用程序的大小