【问题标题】:upgrading SQLite DB in Android using ContentProvider使用 ContentProvider 在 Android 中升级 SQLite DB
【发布时间】:2012-04-21 21:18:25
【问题描述】:

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

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

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

内容提供者 我有一个 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。

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

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

谢谢!

【问题讨论】:

    标签: android sqlite android-contentprovider android-contentresolver sqliteopenhelper


    【解决方案1】:

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

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

    希望对你有帮助

    【讨论】:

    • 这是在用户单击更新按钮时完成的,如您在此处看到的: public void onClick(DialogInterface dialog, int which) { // dialog.dismiss(); int newVersion = preferences.getInt(Settings.DB_VERSION, 1) + 1;编辑器 editor = preferences.edit(); editor.putInt(Settings.DB_VERSION, newVersion); Log.i("Update", "将数据库版本更新为版本:" + newVersion); editor.commit();午餐文件选择器(); }
    • 嗨文斯。我不确定我的回复是否被正确理解。您的建议是在我希望更新数据库时更新版本(下次调用 getReadableDatabase 时)但这将不会发生(因为这正是我正在做的)这是由于事实上,每次调用时都不会调用 contentResolver 的 onCreate,因此不会更新数据库版本。
    【解决方案2】:

    我找到了一个不错的解决方案。 在我的扩展 ContentProviderContactsContentProvider 中,我添加了一个 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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-20
      • 2010-12-16
      • 2011-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多