Java 基础数据库被替换时,游标加载程序未加载新数据
我希望有人能帮我做一些我一直坚持的事情。我搜索了StackOverflow,寻找了一些其他的解决方案,但到目前为止还没有任何效果 我正在使用Java 基础数据库被替换时,游标加载程序未加载新数据,java,android,sqlite,Java,Android,Sqlite,我希望有人能帮我做一些我一直坚持的事情。我搜索了StackOverflow,寻找了一些其他的解决方案,但到目前为止还没有任何效果 我正在使用ContentProvider、CursorLoader和SQLiteOpenHelper将数据从SQLite数据库获取到一些列表视图中。长期以来,这种方法一直运作良好。由于在游标上使用了setNotificationUri和ContentResolver的notifyChange功能,我能够对数据进行更新、删除等操作,并且更改会反映在列表视图中 最近,我为
ContentProvider
、CursorLoader
和SQLiteOpenHelper
将数据从SQLite数据库获取到一些列表视图中。长期以来,这种方法一直运作良好。由于在游标上使用了setNotificationUri
和ContentResolver
的notifyChange
功能,我能够对数据进行更新、删除等操作,并且更改会反映在列表视图中
最近,我为我的应用程序实现了一个云备份功能,将数据库文件备份到云存储以供以后检索。在这一点上,我遇到了问题
我从云中恢复数据库并用入站版本替换本地数据库文件没有问题。但是,执行此操作后,我的游标和加载程序将继续返回数据库文件被替换之前存在的数据。如果退出应用程序并等待其进程结束,然后重新启动它,则会出现新数据
我知道游标和加载程序在整个活动生命周期中存储数据,因此我认为这是我的问题的根源,但我试图使这种缓存行为无效的任何尝试都失败了
到目前为止我检查的内容:
- 验证了在数据库交换之后,
实际上正在被调用,并且onCreateLoader
正在被重新创建。是的CursorLoader
- 已通过
验证新的swapCursor
光标是否已交换到我的
中。是的CursorAdapter
- 当我尝试使用
时,仔细检查我是否使用了正确的URI值。URI值与我为正常CRUD操作更新特定Listview的数据时使用的值匹配notifyChange
SQLiteOpenHelper
对象,而不是依赖于在我的ContentProvider
onCreate
函数中创建的实例。但我认为这是一种不好的做法,会造成打开太多连接的情况,因为我知道每个SQLiteOpenHelper
实例都管理自己的连接
谢谢你的帮助。一些相关的代码片段
DBHelper.java
public class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
...
public void ReplaceDatabase(Context c) throws IOException
{
// First, let's make sure the database is closed...
this.close();
File inboundFile = new File(c.getFilesDir(), this.INCOMING_DATABASE_NAME);
if(!inboundFile.exists()) {
throw new IOException("Incoming Database doesn't exist.");
}
File currentFile = c.getDatabasePath(this.DATABASE_NAME);
if(!currentFile.exists()) {
throw new IOException("Database doesn't exist.");
}
boolean deletionResult = c.deleteFile(this.BACKUP_DATABASE_NAME);
try {
InputStream input = new FileInputStream(currentFile);
File backupFile = new File(c.getFilesDir(),this.BACKUP_DATABASE_NAME);
OutputStream output = new FileOutputStream(backupFile);
byte[] buffer = new byte[1024];
int length;
while ((length = input.read(buffer))>0)
{
output.write(buffer, 0, length);
}
output.flush();
output.close();
input.close();
} catch (FileNotFoundException e) {
throw e;
}
try {
InputStream input = new FileInputStream(inboundFile);
currentFile.delete();
File databaseFile = c.getDatabasePath(this.DATABASE_NAME);
OutputStream output = new FileOutputStream(databaseFile);
byte[] buffer = new byte[1024];
int length;
while ((length = input.read(buffer))>0)
{
output.write(buffer, 0, length);
}
output.flush();
output.close();
input.close();
} catch (FileNotFoundException e) {
throw e;
}
c.getContentResolver().notifyChange(Asset.AssetTable.CONTENT_DETAIL_URI, null);
}
}
public class CoreProvider extends ContentProvider {
private DBHelper dbHelper;
@Override
public boolean onCreate() {
dbHelper = new DBHelper(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder){
// Here I build the query. Then....
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor c = qb.query(
db, // The database to query
projection, // The columns to return from the query
selection, // The columns for the where clause
selectionArgs, // The values for the where clause
null, // don't group the rows
null, // don't filter by row groups
orderBy // The sort order
);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
}
CoreProvider.java
public class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
...
public void ReplaceDatabase(Context c) throws IOException
{
// First, let's make sure the database is closed...
this.close();
File inboundFile = new File(c.getFilesDir(), this.INCOMING_DATABASE_NAME);
if(!inboundFile.exists()) {
throw new IOException("Incoming Database doesn't exist.");
}
File currentFile = c.getDatabasePath(this.DATABASE_NAME);
if(!currentFile.exists()) {
throw new IOException("Database doesn't exist.");
}
boolean deletionResult = c.deleteFile(this.BACKUP_DATABASE_NAME);
try {
InputStream input = new FileInputStream(currentFile);
File backupFile = new File(c.getFilesDir(),this.BACKUP_DATABASE_NAME);
OutputStream output = new FileOutputStream(backupFile);
byte[] buffer = new byte[1024];
int length;
while ((length = input.read(buffer))>0)
{
output.write(buffer, 0, length);
}
output.flush();
output.close();
input.close();
} catch (FileNotFoundException e) {
throw e;
}
try {
InputStream input = new FileInputStream(inboundFile);
currentFile.delete();
File databaseFile = c.getDatabasePath(this.DATABASE_NAME);
OutputStream output = new FileOutputStream(databaseFile);
byte[] buffer = new byte[1024];
int length;
while ((length = input.read(buffer))>0)
{
output.write(buffer, 0, length);
}
output.flush();
output.close();
input.close();
} catch (FileNotFoundException e) {
throw e;
}
c.getContentResolver().notifyChange(Asset.AssetTable.CONTENT_DETAIL_URI, null);
}
}
public class CoreProvider extends ContentProvider {
private DBHelper dbHelper;
@Override
public boolean onCreate() {
dbHelper = new DBHelper(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder){
// Here I build the query. Then....
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor c = qb.query(
db, // The database to query
projection, // The columns to return from the query
selection, // The columns for the where clause
selectionArgs, // The values for the where clause
null, // don't group the rows
null, // don't filter by row groups
orderBy // The sort order
);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
}
请看。@CL-我确实重用了这个名称,尽管我不必这样做。这是可以改变的。不过,我真正需要解决的是缓存问题。只要连接可能仍然打开,就不能删除或移动旧数据库文件。你找到解决方案了吗?@DANGERZONE94没有。我没有。