当底层数据库被替换时,CursorLoader不加载新数据

时间:2017-10-17 22:12:24

标签: java android sqlite

我希望有人可以用我坚持的东西来帮助我。我已经搜索了StackOverflow查看其他一些解决方案,到目前为止还没有任何工作。

我使用ContentProviderCursorLoaderSQLiteOpenHelper将SQLite数据库中的数据导入某些ListView。这已经很好地工作了很长时间。我能够对数据进行更新,删除等操作,并且由于在游标和setNotificationUri的{​​{1}} ContentResolver上使用notifyChange,所以更改会反映在ListView中{1}}功能。

最近,我为我的应用程序实现了云备份功能,其中数据库文件备份到云存储以供以后检索。在这一点上,我遇到了问题。

我可以毫不费力地将数据库从云中恢复,并使用入站版本替换本地数据库文件。但是,执行此操作后,我的游标和加载器将继续返回数据,因为它在替换数据库文件之前存在。如果我退出应用程序并等待其进程结束,然后重新启动它,则会显示新数据。

我知道游标和加载器会在整个Activity生命周期中存储数据,所以我认为这是我遇到麻烦的根源,但是我在使这种缓存行为失效方面所做的任何尝试都失败了。

到目前为止我检查过的内容:

  • 已验证onCreateLoader实际上是在数据库交换后调用并且正在重新创建CursorLoader。它是。
  • 已验证新Cursor已通过CursorAdapterswapCursor交换。它是。
  • 在我尝试使用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;
}
}

0 个答案:

没有答案
相关问题