java.lang.RuntimeException:无法复制数据库文件。尝试预填充房间数据库时发生
我试图用一个database2.db文件预先填充我的Android房间,我从我的设备上复制了这个文件,让应用程序实际地生成数据库值。这在我最初安装应用程序时起作用,但是在卸载和重新安装以强制构建房间数据库时,我遇到以下错误java.lang.RuntimeException:无法复制数据库文件。尝试预填充房间数据库时发生,java,android,database,android-room,Java,Android,Database,Android Room,我试图用一个database2.db文件预先填充我的Android房间,我从我的设备上复制了这个文件,让应用程序实际地生成数据库值。这在我最初安装应用程序时起作用,但是在卸载和重新安装以强制构建房间数据库时,我遇到以下错误 E/AndroidRuntime: FATAL EXCEPTION: arch_disk_io_0 Process: com.Adictya.timely, PID: 16244 java.lang.RuntimeException: Exception while comp
E/AndroidRuntime: FATAL EXCEPTION: arch_disk_io_0
Process: com.Adictya.timely, PID: 16244
java.lang.RuntimeException: Exception while computing database live data.
at androidx.room.RoomTrackingLiveData$1.run(RoomTrackingLiveData.java:92)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Caused by: java.lang.RuntimeException: Unable to copy database file.
at androidx.room.SQLiteCopyOpenHelper.verifyDatabaseFile(SQLiteCopyOpenHelper.java:131)
.
.
.
.
Caused by: java.io.FileNotFoundException: database/database2.db
at com.Adictya.timely.data.TimeSlotsDAO_Impl$7.call(TimeSlotsDAO_Impl.java:313)
.
.
.
一旦我删除.createfromaset(“database/database2.db
)`并且我已经确保该文件位于assets/database包中,应用程序就可以正常工作
这是我的数据库课
@Database(entities = {Classes.class, TimeSlots.class}, version = 1, exportSchema = false)
public abstract class TimeSlotsRoomDatabase extends RoomDatabase {
public static volatile TimeSlotsRoomDatabase INSTANCE;
public abstract ClassesDAO classesDAO();
public abstract TimeSlotsDAO timeSlotsDAO();
public static TimeSlotsRoomDatabase getDatabase(final Context context){
if (INSTANCE == null){
synchronized (TimeSlotsRoomDatabase.class){
if (INSTANCE == null){
//create our db
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),TimeSlotsRoomDatabase.class,"timeslots_db")
.addCallback(roomDatabaseCallback).createFromAsset("database/database2.db").fallbackToDestructiveMigration().build();
// INSTANCE = Room.databaseBuilder(context.getApplicationContext(),TimeSlotsRoomDatabase.class,"timeslots_db")
// .addCallback(roomDatabaseCallback).build();
}
}
}
return INSTANCE;
}
public static RoomDatabase.Callback roomDatabaseCallback = new RoomDatabase.Callback() {
@Override
public void onOpen(@NonNull SupportSQLiteDatabase db){
super.onOpen(db);
new PopulateDbAsync(INSTANCE).execute();
}
};
private static class PopulateDbAsync extends AsyncTask<Void, Void, Void>{
private final TimeSlotsDAO timeSlotsDAO;
private final ClassesDAO classesDAO;
public PopulateDbAsync(TimeSlotsRoomDatabase db){
timeSlotsDAO = db.timeSlotsDAO();
classesDAO = db.classesDAO();
}
@Override
protected Void doInBackground(Void... voids) {
timeSlotsDAO.deleteAll();
classesDAO.deleteAll();
//for testing
Classes classes = new Classes("CSE1002","Microprocessor and Interfacing","Micro");
classes = new Classes("CSE1003","Internet of Things","IOT");
TimeSlots timeSlots = new TimeSlots("A1",0,0,"8:00 AM","Microprocessor and Interfacing","SJT-522");
timeSlotsDAO.insert(timeSlots);
}
}
}
@Database(entities={Classes.class,TimeSlots.class},version=1,exportSchema=false)
公共抽象类TimeSlotsRoomDatabase扩展了RoomDatabase{
公共静态易失性TimeSlotsRoomDatabase实例;
公共抽象类dao ClassesDAO();
公共抽象TimeSlotsDAO TimeSlotsDAO();
公共静态TimeSlotsRoomDatabase getDatabase(最终上下文){
if(实例==null){
已同步(TimeSlotsRoomDatabase.class){
if(实例==null){
//创建我们的数据库
INSTANCE=Room.databaseBuilder(context.getApplicationContext(),TimeSlotsRoomDatabase.class,“timeslots\u db”)
.addCallback(roomDatabaseCallback).createFromAsset(“database/database2.db”).fallbackToDestructiveMigration().build();
//INSTANCE=Room.databaseBuilder(context.getApplicationContext(),TimeSlotsRoomDatabase.class,“timeslots\u db”)
//.addCallback(roomDatabaseCallback).build();
}
}
}
返回实例;
}
public static RoomDatabase.Callback roomDatabaseCallback=新建RoomDatabase.Callback(){
@凌驾
public void onOpen(@NonNull SupportSQLiteDatabase db){
super.onOpen(db);
新填充的Basync(实例).execute();
}
};
私有静态类填充Basync扩展异步任务{
专用最终TimeSlotsDAO TimeSlotsDAO;
私有最终类dao ClassesDAO;
公共填充基本同步(TimeSlotsRoomDatabase db){
timeSlotsDAO=db.timeSlotsDAO();
classesDAO=db.classesDAO();
}
@凌驾
受保护的空位背景(空位…空位){
timeSlotsDAO.deleteAll();
classesDAO.deleteAll();
//用于测试
类别=新类别(“CSE1002”、“微处理器和接口”、“微型”);
类别=新类别(“CSE1003”、“物联网”、“物联网”);
时隙时隙=新时隙(“A1”,0,0,“上午8:00”,“微处理器和接口”,“SJT-522”);
timeSlotsDAO.insert(时隙);
}
}
}
我犯了一个愚蠢的错误,将assets文件夹放在了我的/java主目录中
作为src/的子目录,使其成为java/、res/等的对等目录
再次感谢您的帮助。如果您有一个小错误,请将
.createFromAsset(“database/database2.db)
替换为.createFromAsset(“databases/database2.db”)
。数据库包将是数据库/
,而不是在此处输入代码
您应该将文件放在app/src/main/assets/databases/database2.db
目录下,并按以下方式对其进行寻址。createfromsete(“databases/database2.db”)
使用Android Studio中的APK Analyzer确认数据库确实打包在您认为的APK中。似乎不是这样?同意,它似乎不在APK中。您确定您的资产/
目录位于正确的位置吗(作为src/
的子目录,使其成为java/
、res/
等的对等目录)。不,我把它放在java/main文件夹中。这是一个愚蠢的错误。移动它解决了问题。非常感谢您的帮助。