简体   繁体   中英

upgrading SQLite DB in Android using ContentProvider

I'm developing an app and using SQLite, contentResolver and contentProvider.

Application description My app searches for contacts in internal 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().

ContentProvider I have a ContactsContentProvider class that extends ContentProvider and holds a reference to ContactsDBAdapter which is my database adapter that extends 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

@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.

Although there are a lot of explanation of how to use both contentProvider and contentResolver I didn't find anywhere a good upgrade progress.

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.

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.

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

    @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().

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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