简体   繁体   English

使用ContentProvider在Android中升级SQLite DB

[英]upgrading SQLite DB in Android using ContentProvider

I'm developing an app and using SQLite, contentResolver and contentProvider. 我正在开发一个应用程序,并使用SQLite,contentResolver和contentProvider。

Application description My app searches for contacts in internal SQLite DB. 应用程序描述我的应用程序在内部SQLite DB中搜索联系人。 the data arrives from external file that is selected on first lunch or when the user press the update option in the menu. 数据来自在第一顿午餐或用户按菜单中的更新选项时选择的外部文件。

All access to the DB are done using getContentResolver(). 使用getContentResolver()完成对数据库的所有访问。

ContentProvider I have a ContactsContentProvider class that extends ContentProvider and holds a reference to ContactsDBAdapter which is my database adapter that extends SQLiteOpenHelper . ContentProvider我有一个ContactsContentProvider类,该类扩展了ContentProvider并持有对ContactsDBAdapter的引用,这是我的数据库适配器,它扩展了SQLiteOpenHelper (I hope you are all with me until now ). (我希望直到现在都和我在一起)。

Problem description When a user press the update button I want the DB to drop all tables and load the new data (this is done by my file chooser and works great). 问题描述当用户按下更新按钮时,我希望数据库删除所有表并加载新数据(这是由我的文件选择器完成的,效果很好)。 in order for the onUpgrade() in my ContactsDBAdapter to work the content provider onCreate() must be called with a higher version then what it had before 为了使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;
}

But I get the contentProvider from my contentResolver so it is not created twice. 但是我从contentResolver获取contentProvider ,因此不会创建两次。

Although there are a lot of explanation of how to use both contentProvider and contentResolver I didn't find anywhere a good upgrade progress. 尽管有很多关于如何同时使用contentProvidercontentResolver的说明,但我在任何地方都找不到很好的升级进度。

I'm aware of how the onUpgrade works and that it is being checked during getReadableDatabase() and getWritableDatabase() calls but the fact is that the version will not be diferent since the ContactsDBAdapter is the same instance as it previously was. 我知道onUpgrade的工作方式,并在getReadableDatabase()getWritableDatabase()调用期间对其进行了检查,但事实是该版本不会有所不同,因为ContactsDBAdapter与以前的实例相同。

I thought about some work arounds but didn't like them at all. 我想到了一些解决方法,但根本不喜欢它们。 I can manually check during insert() if the version is higher (but that would be expensive since it is done by every call) and if the answer is true then manually call onUpgrade. 我可以在insert()期间手动检查版本是否更高(但这会很昂贵,因为每次调用都会完成),如果答案为true,则手动调用onUpgrade。

or to try and unregister the Provider in some way but didn't find any valid and good solution so far. 或尝试以某种方式注销提供者,但到目前为止仍未找到任何有效且好的解决方案。

What is the best practice to upgrade your DB ? 升级数据库的最佳实践是什么?

Thanks! 谢谢!

I would suggest you update the shared preferences to change the db version and add it: 我建议您更新共享首选项以更改数据库版本并添加它:

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

Hopefully it helps you 希望它对您有帮助

I found a nice solution. 我找到了一个不错的解决方案。 In my ContactsContentProvider which extends ContentProvider I added a sharedPrefencesListener 在扩展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);
    }
   }
}
};

Now when the user changes the version number in my main activity then I set the version number. 现在,当用户在我的主要活动中更改版本号时,我将设置版本号。 This will call a new ContactsDBAdapter which will then invoke onUpgrade the next time someone will want getReadableDatabase() or getWriteableDatabase(). 这将调用一个新的ContactsDBAdapter,该适配器将在下次有人需要getReadableDatabase()或getWriteableDatabase()时调用onUpgrade。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM