存在新数据库版本时从资产复制数据库

时间:2012-11-27 21:13:05

标签: android database android-assets

我正在尝试解决以下问题。我有一个使用预先创建的数据库的应用程序。我把这个数据库放在assets文件夹中。然后我复制数据库internaly。

我希望能够检查我的数据库的版本,所以当有新版本时,我删除旧数据库并从assets文件夹中复制新数据库。我将数据库版本存储为共享首选项数据。

运行以下代码我收到错误,应用程序停止运行(已经停止了)。 你能帮帮我一下,找出问题所在吗?

   public class DatabaseConnector
     {
// database name
   private static final String DATABASE_NAME = "Recipes";
   private SQLiteDatabase database; // database object
   private DatabaseOpenHelper databaseOpenHelper; // database helper

   String selection;       

   // public constructor for DatabaseConnector
   public DatabaseConnector(Context context) 
   {
      // create a new DatabaseOpenHelper
      databaseOpenHelper = 
         new DatabaseOpenHelper(context, DATABASE_NAME, null, 1);
   } // end DatabaseConnector constructor

   // open the database connection
   // attempts to establish a connection to the db
   // and throws an exception if it fails
   public void open() throws SQLException 
   {
      // create or open a database for reading/writing
      database = databaseOpenHelper.getWritableDatabase();
   } // end method open

   // close the database connection
   public void close() 
   {
      if (database != null)
         database.close(); // close the database connection
   } // end method close

   // inserts a new esoda in the database
   public void insertEsoda(String title, String category, String ingredients, String process, 
      String notes, String image, String time, String calories, String difficulty) 
   {
....
   } // end method insertEsoda

   // updates a esoda in the database
   public void updateEsoda(long id, String title, String category, String ingredients, 
      String process, String notes, String image, String time, String calories, String difficulty) 
   {
      ....
   } // end method updateEsoda


// updates favorites in the database
   public Boolean updateFavorite(long id) 
   {
....
   } // end method update favorites


   // return a Cursor with all esoda information in the database
   public Cursor getAllEsoda() 
   {
     ....
   } // end method getAllEsoda


   // return a Cursor with all esoda information in the database
   public Cursor getRecipeCategory(int position) 
   {
      ....
   } // end method getAllEsoda


   // get a Cursor containing all information about the esoda specified
   // by the given id
   public Cursor getOneEsoda(long id) 
   {
     ....
   } // end method getOneEsoda


   // delete the contact specified by the given String name
   public void deleteEsoda(long id) 
   {
     ....
   } // end method deleteEsoda


   private class DatabaseOpenHelper extends SQLiteOpenHelper {
       public Context mContext;
       private static final int DATABASE_VERSION = 1;
       private static final String SP_KEY_DB_VER = "db_ver";

      // public constructor
      public DatabaseOpenHelper(Context context, String title,
         CursorFactory factory, int version) 
      {
         super(context, title, factory, version);
         mContext=context;
         initialize();
      } // end DatabaseOpenHelper constructor

      private void initialize() {

          if (databaseExists()) {
              SharedPreferences prefs = PreferenceManager
                      .getDefaultSharedPreferences(mContext);
              int dbVersion = prefs.getInt(SP_KEY_DB_VER, 1);
              if (DATABASE_VERSION != dbVersion) {
                  File dbFile = mContext.getDatabasePath(DATABASE_NAME);
                  if (!dbFile.delete()) {
                      Log.w("TAG", "Unable to update database");
                  }
              }
          }
          if (!databaseExists()) {
              createDatabase();
          }
      }

      private boolean databaseExists() {
          File dbFile = mContext.getDatabasePath(DATABASE_NAME);
          return dbFile.exists();
      }

      private void createDatabase() {
          String parentPath = mContext.getDatabasePath(DATABASE_NAME).getParent();
          String path = mContext.getDatabasePath(DATABASE_NAME).getPath();

          File file = new File(parentPath);
          if (!file.exists()) {
              if (!file.mkdir()) {
                  Log.w("TAG", "Unable to create database directory");
                  return;
              }
          }

          InputStream is = null;
          OutputStream os = null;
          try {
              is = mContext.getAssets().open(DATABASE_NAME);
              os = new FileOutputStream(path);

              byte[] buffer = new byte[1024];
              int length;
              while ((length = is.read(buffer)) > 0) {
                  os.write(buffer, 0, length);
              }
              os.flush();
              SharedPreferences prefs = PreferenceManager
                      .getDefaultSharedPreferences(mContext);
              SharedPreferences.Editor editor = prefs.edit();
              editor.putInt(SP_KEY_DB_VER, DATABASE_VERSION);
              editor.commit();
          } catch (IOException e) {
              e.printStackTrace();
          } finally {
              if (is != null) {
                  try {
                      is.close();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
              if (os != null) {
                  try {
                      os.close();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
          }
      }



      // creates the contacts table when the database is created
      @Override
      public void onCreate(SQLiteDatabase db) 
      {
         // query to create a new table named contacts
         String createQuery = "CREATE TABLE recipes" +
            "(_id integer primary key autoincrement," +
            "title TEXT, category TEXT, ingredients TEXT, process TEXT, notes TEXT, image TEXT, " +
            "time TEXT, calories TEXT, difficulty TEXT);";

         db.execSQL(createQuery); // execute the query
      } // end method onCreate

      @Override
      public void onUpgrade(SQLiteDatabase db, int oldVersion, 
          int newVersion) 
      {
      } // end method onUpgrade
   } // end class DatabaseOpenHelper
}

这是我的LogCat文本:

11-27 23:19:41.643: D/AndroidRuntime(297): Shutting down VM
11-27 23:19:41.643: W/dalvikvm(297): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
11-27 23:19:41.673: E/AndroidRuntime(297): FATAL EXCEPTION: main
11-27 23:19:41.673: E/AndroidRuntime(297): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{development.nk.cretanrecipes/development.nk.cretanrecipes.RecipesMainActivity}: java.lang.NullPointerException
11-27 23:19:41.673: E/AndroidRuntime(297):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2585)
11-27 23:19:41.673: E/AndroidRuntime(297):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
11-27 23:19:41.673: E/AndroidRuntime(297):  at android.app.ActivityThread.access$2300(ActivityThread.java:125)
11-27 23:19:41.673: E/AndroidRuntime(297):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
11-27 23:19:41.673: E/AndroidRuntime(297):  at android.os.Handler.dispatchMessage(Handler.java:99)
11-27 23:19:41.673: E/AndroidRuntime(297):  at android.os.Looper.loop(Looper.java:123)
11-27 23:19:41.673: E/AndroidRuntime(297):  at android.app.ActivityThread.main(ActivityThread.java:4627)
11-27 23:19:41.673: E/AndroidRuntime(297):  at java.lang.reflect.Method.invokeNative(Native Method)
11-27 23:19:41.673: E/AndroidRuntime(297):  at java.lang.reflect.Method.invoke(Method.java:521)
11-27 23:19:41.673: E/AndroidRuntime(297):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
11-27 23:19:41.673: E/AndroidRuntime(297):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
11-27 23:19:41.673: E/AndroidRuntime(297):  at dalvik.system.NativeStart.main(Native Method)
11-27 23:19:41.673: E/AndroidRuntime(297): Caused by: java.lang.NullPointerException
11-27 23:19:41.673: E/AndroidRuntime(297):  at android.content.ContextWrapper.getResources(ContextWrapper.java:80)
11-27 23:19:41.673: E/AndroidRuntime(297):  at android.widget.Toast.<init>(Toast.java:89)
11-27 23:19:41.673: E/AndroidRuntime(297):  at android.widget.Toast.makeText(Toast.java:231)
11-27 23:19:41.673: E/AndroidRuntime(297):  at development.nk.cretanrecipes.DatabaseConnector$DatabaseOpenHelper.initialize(DatabaseConnector.java:191)
11-27 23:19:41.673: E/AndroidRuntime(297):  at development.nk.cretanrecipes.DatabaseConnector$DatabaseOpenHelper.<init>(DatabaseConnector.java:186)
11-27 23:19:41.673: E/AndroidRuntime(297):  at development.nk.cretanrecipes.DatabaseConnector.<init>(DatabaseConnector.java:35)
11-27 23:19:41.673: E/AndroidRuntime(297):  at development.nk.cretanrecipes.RecipesMainActivity.<init>(RecipesMainActivity.java:32)
11-27 23:19:41.673: E/AndroidRuntime(297):  at java.lang.Class.newInstanceImpl(Native Method)
11-27 23:19:41.673: E/AndroidRuntime(297):  at java.lang.Class.newInstance(Class.java:1429)
11-27 23:19:41.673: E/AndroidRuntime(297):  at android.app.Instrumentation.newActivity(Instrumentation.java:1021)
11-27 23:19:41.673: E/AndroidRuntime(297):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2577)
11-27 23:19:41.673: E/AndroidRuntime(297):  ... 11 more

1 个答案:

答案 0 :(得分:1)

stacktrace中的错误似乎与toast有关,而toast没有出现在你粘贴的代码中。

但是,此库sqllite asset helper似乎解决了您尝试解决的同一问题。

“使用应用程序的原始资产文件管理数据库创建和版本管理的Android帮助程序类。”

希望有所帮助