Java 基础数据库被替换时,游标加载程序未加载新数据

Java 基础数据库被替换时,游标加载程序未加载新数据,java,android,sqlite,Java,Android,Sqlite,我希望有人能帮我做一些我一直坚持的事情。我搜索了StackOverflow,寻找了一些其他的解决方案,但到目前为止还没有任何效果 我正在使用ContentProvider、CursorLoader和SQLiteOpenHelper将数据从SQLite数据库获取到一些列表视图中。长期以来,这种方法一直运作良好。由于在游标上使用了setNotificationUri和ContentResolver的notifyChange功能,我能够对数据进行更新、删除等操作,并且更改会反映在列表视图中 最近,我为

我希望有人能帮我做一些我一直坚持的事情。我搜索了StackOverflow,寻找了一些其他的解决方案,但到目前为止还没有任何效果

我正在使用
ContentProvider
CursorLoader
SQLiteOpenHelper
将数据从SQLite数据库获取到一些列表视图中。长期以来,这种方法一直运作良好。由于在游标上使用了
setNotificationUri
ContentResolver
notifyChange
功能,我能够对数据进行更新、删除等操作,并且更改会反映在列表视图中

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

我从云中恢复数据库并用入站版本替换本地数据库文件没有问题。但是,执行此操作后,我的游标和加载程序将继续返回数据库文件被替换之前存在的数据。如果退出应用程序并等待其进程结束,然后重新启动它,则会出现新数据

我知道游标和加载程序在整个活动生命周期中存储数据,因此我认为这是我的问题的根源,但我试图使这种缓存行为无效的任何尝试都失败了

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

  • 验证了在数据库交换之后,
    onCreateLoader
    实际上正在被调用,并且
    CursorLoader
    正在被重新创建。是的
  • 已通过
    swapCursor
    验证新的
    光标是否已交换到我的
    CursorAdapter
    中。是的
  • 当我尝试使用
    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);

    }

}
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没有。我没有。