我希望有人可以用我坚持的东西来帮助我。我已经搜索了StackOverflow查看其他一些解决方案,到目前为止还没有任何工作。
我使用ContentProvider
,CursorLoader
和SQLiteOpenHelper
将SQLite数据库中的数据导入某些ListView。这已经很好地工作了很长时间。我能够对数据进行更新,删除等操作,并且由于在游标和setNotificationUri
的{{1}} ContentResolver
上使用notifyChange
,所以更改会反映在ListView中{1}}功能。
最近,我为我的应用程序实现了云备份功能,其中数据库文件备份到云存储以供以后检索。在这一点上,我遇到了问题。
我可以毫不费力地将数据库从云中恢复,并使用入站版本替换本地数据库文件。但是,执行此操作后,我的游标和加载器将继续返回数据,因为它在替换数据库文件之前存在。如果我退出应用程序并等待其进程结束,然后重新启动它,则会显示新数据。
我知道游标和加载器会在整个Activity生命周期中存储数据,所以我认为这是我遇到麻烦的根源,但是我在使这种缓存行为失效方面所做的任何尝试都失败了。
到目前为止我检查过的内容:
onCreateLoader
实际上是在数据库交换后调用并且正在重新创建CursorLoader
。它是。Cursor
已通过CursorAdapter
与swapCursor
交换。它是。notifyChange
时,仔细检查我是否使用了正确的URI值。 URI值与我在为正常CRUD操作更新特定Listview的数据时使用的内容相匹配。唯一有效的方法是在每次查询之前重新创建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);
}
}
CoreProvider.java
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;
}
}