1

我正在开发一个应用程序并使用 SQLite、contentResolver 和 contentProvider。

应用程序描述 我的应用程序在内部 SQLite DB 中搜索联系人。数据来自在第一次午餐或用户按下菜单中的更新选项时选择的外部文件。

对数据库的所有访问都是使用 getContentResolver() 完成的。

ContentProvider 我有一个ContactsContentProvider类,它扩展ContentProvider并保存对ContactsDBAdapter的引用,这是我扩展SQLiteOpenHelper的数据库适配器。(我希望你们都和我在一起直到现在)。

问题描述 当用户按下更新按钮时,我希望数据库删除所有表并加载新数据(这是由我的文件选择器完成的,效果很好)。为了使我的ContactsDBAdapter中的onUpgrade()工作,内容提供程序 onCreate() 必须使用比以前更高的版本调用

@Override
public boolean onCreate() {
      context = getContext();
      pref = PreferenceManager.getDefaultSharedPreferences(context);
      int dbVersion = pref.getInt(Settings.DB_VERSION, 1);
      mDb = new ContactsDBAdapter(context,dbVersion);
      return (mDb == null)? false : true;
}

但是我从我的contentResolver中获取了contentProvider ,所以它不会被创建两次。

虽然有很多关于如何使用contentProvidercontentResolver的解释,但我没有找到任何好的升级进度。

我知道 onUpgrade 是如何工作的,并且在getReadableDatabase()getWritableDatabase()调用期间对其进行检查,但事实是版本不会不同,因为ContactsDBAdapter与以前的实例相同。

我想过一些变通办法,但根本不喜欢它们。我可以在 insert() 期间手动检查版本是否更高(但这会很昂贵,因为每次调用都会完成),如果答案为真,则手动调用 onUpgrade。

或尝试以某种方式注销提供程序,但到目前为止没有找到任何有效且良好的解决方案。

升级数据库的最佳做法是什么?

谢谢!

4

2 回答 2

1

我建议您更新共享首选项以更改数据库版本并添加它:

SharedPreferences.Editor ed = pref.edit();
ed.putInt(Settings.DB_VERSION, dbVersion + 1);
ed.commit();

希望它可以帮助你

于 2012-04-21T21:38:55.700 回答
0

我找到了一个不错的解决方案。在扩展ContentProvider的ContactsContentProvider中,我添加了一个sharedPrefencesListener

    @Override
public boolean onCreate() {
      context = getContext();
      pref = PreferenceManager.getDefaultSharedPreferences(context);
      int dbVersion = pref.getInt(Settings.DB_VERSION, 1);
      mDb = new ContactsDBAdapter(context,dbVersion);
      pref.registerOnSharedPreferenceChangeListener(sharedPrefListener) ;
      return (mDb == null)? false : true;
}
SharedPreferences.OnSharedPreferenceChangeListener sharedPrefListener = 
  new SharedPreferences.OnSharedPreferenceChangeListener() {

    @Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, 
     String key) {
   if(key.equals(Settings.DB_VERSION)){
    int dbVersion = sharedPreferences.getInt(Settings.DB_VERSION, 1);
    synchronized (mDb) {
            mDb.close();//Not sure this is the right behavior
        mDb = new ContactsDBAdapter(context,dbVersion);
    }
   }
}
};

现在,当用户在我的主要活动中更改版本号时,我会设置版本号。这将调用一个新的 ContactsDBAdapter,然后在下次有人需要 getReadableDatabase() 或 getWriteableDatabase() 时调用 onUpgrade。

于 2012-04-22T17:44:56.480 回答