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.非常感谢鲍勃。。我将尝试这样做,希望它不会影响应用程序的大小