如何解决使用Room的createFromAsset在数据库文件之间切换会返回空数据库
我有一个spinner
,可用来在SQLite
数据库文件之间切换。在spinner
选择侦听器上,我将相关的数据库文件名传递给Room的Database类。
在通过调用Room的createFromAsset()
在数据库之间进行切换之前,我删除Room的数据库文件以避免来自先前数据库的数据缓存。
我的问题是,每当我切换到另一个spinner
值时,数据库都不会返回任何内容。从我手机上的应用程序数据中读取数据库文件后,该数据库文件已存在,但该表没有任何条目。
这是微调器回调:
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent,View view,int position,long id) {
if (mActivateSpinner) {
String newDatabaseName;
switch (position) {
case 0:
newDatabaseName = "database1.db";
break;
case 1:
newDatabaseName = "database2.db";
break;
default:
newDatabaseName = "database1.db";
}
mViewModel.deleteDatabase(newDatabaseName,() -> runOnUiThread(() -> {
//
// Reading database here returns empty data
//
}));
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
ViewModel相关方法
public class MyViewModel extends AndroidViewModel {
....
MyRepository mRepository;
public void deleteDatabase(String newDatabaseName,OnCompletionListener listener) {
MyRepository.resetInstance();
MyDataBase.resetInstance();
// delete current Room database file
deleteDatabaseFile(getApplication().getApplicationContext(),"MyDataBaseFile.db",() -> initRepository(newDatabaseName,listener));
}
public void initRepository(String newDatabaseName,OnCompletionListener listener) {
mRepository = MyRepository.getInstance(getApplication(),newDatabaseName,listener);
}
public static void deleteDatabaseFile(Context context,String fileName,OnCompletionListener deleteListener) {
new Thread(() -> {
File parent = new File(context.getApplicationInfo().dataDir + "/databases");
File db = new File(parent,fileName);
if (db.delete()) {
deleteListener.onComplete();
Log.d("TAG","Database deleted");
} else
Log.d("TAG","Failed to delete database");
}).start();
}
}
与存储库相关的方法
public class MyRepository {
...
private MyDataBaseDao mDao;
private static MyRepository INSTANCE;
public static MyRepository getInstance(Application application,String databaseName,OnCompletionListener listener) {
if (INSTANCE == null) {
INSTANCE = new MyRepository(application,databaseName,listener);
}
return INSTANCE;
}
private MyRepository(Application application,OnCompletionListener listener) {
mDao = MyDataBase.getInstance(application.getApplicationContext(),listener).getDao();
}
}
房间数据库
@Database(entities = {MyTable.class},version = 1,exportSchema = false)
public abstract class MyDataBase extends RoomDatabase {
public static final String DATABASE_NAME = "MyDataBaseFile.db";
private static volatile MyDataBase INSTANCE;
private static final Object LOCK = new Object();
public abstract MyDataBaseDao getDao();
public static void resetInstance() {
INSTANCE = null;
}
static public MyDataBase getInstance(final Context context,OnCompletionListener listener) {
if (INSTANCE == null) {
synchronized (LOCK) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),MyDataBase.class,DATABASE_NAME)
.createFromAsset("database/" + databaseName)
.build();
if (listener != null)
listener.onComplete();
}
}
}
return INSTANCE;
}
}
listener.onComplete()
被调用,并且数据库文件在那里具有预期的大小,但是表中没有数据。
解决方法
Room为每个数据库创建3个文件,在本例中,我将数据库命名为MyDataBaseFile.db
,然后Room创建3个文件并将其命名为:
- MyDataBaseFile.db
- MyDataBaseFile.db-wal
- MyDataBaseFile.db-shm
当我切换微调器值时,我只是删除MyDataBaseFile.db
而保留其他两个文件,而删除其他两个文件的确确实在表中显示了新数据
更新了删除方法
public static void deleteDatabase(Context context,String databaseName,OnCompletionListener deleteListener) {
new Thread(() -> {
File parent = new File(context.getApplicationInfo().dataDir + "/databases");
if (deleteFile(parent,databaseName + "-wal")
&& deleteFile(parent,databaseName + "-shm")
&& deleteFile(parent,databaseName)) {
deleteListener.onComplete();
Log.d(TAG,"Database deleted");
} else
Log.d(TAG,"Failed to delete database");
}).start();
}
/*
* Returns:
* **** true: if the file doesn't exist or successfully deleted
* **** false: if the file can't be deleted
* */
private static boolean deleteFile(File parent,String child) {
File file;
if (parent != null)
file = new File(parent,child);
else
file = new File(child);
if (file.exists())
return file.delete();
else
return true;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。