2011-09-21 96 views
0

我正在研究使用SQLite上的数据库的应用程序。我有一个自定义DatabaseHelper类,它创建两个不同的sqlite数据库并从资产文件夹中复制它们。我有的问题是我可以“T集不同situations.Here要使用哪个数据库是我DatabaseHelper类看起来像:Android更改数据库

import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 

import android.content.ContentValues; 
import android.content.Context; 
import android.database.Cursor; 
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteDatabase.CursorFactory; 
import android.database.sqlite.SQLiteException; 
import android.database.sqlite.SQLiteOpenHelper; 
import android.util.Log; 

public class DataBaseHelper extends SQLiteOpenHelper{ 

    private static SQLiteDatabase sqliteDb; 
    private static DataBaseHelper instance; 
    private static final int DATABASE_VERSION = 1; 
    // the default database path is : 
    // /data/data/pkgNameOfYourApplication/databases/ 
    private static String DB_PATH_PREFIX = "/data/data/"; 
    private static String DB_PATH_SUFFIX = "/databases/"; 
    private static final String TAG = "DataBaseHelper"; 
    private Context context; 

    /*** 
    * Contructor 
    * 
    * @param context 
    *   : app context 
    * @param name 
    *   : database name 
    * @param factory 
    *   : cursor Factory 
    * @param version 
    *   : DB version 
    */ 
    public DataBaseHelper(Context context, String name, 
        CursorFactory factory, int version) { 
      super(context, name, factory, version); 
      this.context = context; 
      Log.i(TAG, "Create or Open database : " + name); 
    } 

    /*** 
    * Initialize method 
    * 
    * @param context 
    *   : application context 
    * @param databaseName 
    *   : database name 
    */ 
    public static void initialize(Context context, String databaseName) { 
      if (instance == null) { 
        /** 
        * Try to check if there is an Original copy of DB in asset 
        * Directory 
        */ 
        if (!checkDatabase(context, databaseName)) { 
          // if not exists, I try to copy from asset dir 
          try { 
           copyDataBase(context, databaseName); 
          } catch (IOException e) { 
            Log.e(TAG,"Database "+ databaseName+" does not exists and there is no Original Version in Asset dir"); 
          } 
        } 

        Log.i(TAG, "Try to create instance of database (" + databaseName 
            + ")"); 
        instance = new DataBaseHelper(context, databaseName, 
            null, DATABASE_VERSION); 
        sqliteDb = instance.getWritableDatabase(); 
        Log.i(TAG, "instance of database (" + databaseName + ") created !"); 
      } 
    } 

    /*** 
    * Static method for getting singleton instance 
    * 
    * @param context 
    *   : application context 
    * @param databaseName 
    *   : database name 
    * @return : singleton instance 
    */ 
    public static final DataBaseHelper getInstance(
        Context context, String databaseName) { 
      initialize(context, databaseName); 
      return instance; 
    } 

    /*** 
    * Method to get database instance 
    * 
    * @return database instance 
    */ 
    public SQLiteDatabase getDatabase() { 
      return sqliteDb; 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
      Log.d(TAG, "onCreate : nothing to do"); 

    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
      Log.d(TAG, "onUpgrade : nothing to do"); 

    } 

    /*** 
    * Method for Copy the database from asset directory to application's data 
    * directory 
    * 
    * @param databaseName 
    *   : database name 
    * @throws IOException 
    *    : exception if file does not exists 
    */ 
    public void copyDataBase(String databaseName) throws IOException { 
      copyDataBase(context, databaseName); 
    } 

    /*** 
    * Static method for copy the database from asset directory to application's 
    * data directory 
    * 
    * @param aContext 
    *   : application context 
    * @param databaseName 
    *   : database name 
    * @throws IOException 
    *    : exception if file does not exists 
    */ 
    private static void copyDataBase(Context aContext, String databaseName) 
        throws IOException { 

      // Open your local db as the input stream 
      InputStream myInput = aContext.getAssets().open(databaseName); 

      // Path to the just created empty db 
      String outFileName = getDatabasePath(aContext, databaseName); 

      Log.i(TAG, "Check if create dir : " + DB_PATH_PREFIX 
          + aContext.getPackageName() + DB_PATH_SUFFIX); 

      // if the path doesn't exist first, create it 
      File f = new File(DB_PATH_PREFIX + aContext.getPackageName() 
          + DB_PATH_SUFFIX); 
      if (!f.exists()) 
        f.mkdir(); 

      Log.i(TAG, "Trying to copy local DB to : " + outFileName); 

      // Open the empty db as the output stream 
      OutputStream myOutput = new FileOutputStream(outFileName); 

      // transfer bytes from the inputfile to the outputfile 
      byte[] buffer = new byte[1024]; 
      int length; 
      while ((length = myInput.read(buffer)) > 0) { 
        myOutput.write(buffer, 0, length); 
      } 

      // Close the streams 
      myOutput.flush(); 
      myOutput.close(); 
      myInput.close(); 

      Log.i(TAG, "DB (" + databaseName + ") copied!"); 
    } 

    /*** 
    * Method to check if database exists in application's data directory 
    * 
    * @param databaseName 
    *   : database name 
    * @return : boolean (true if exists) 
    */ 
    public boolean checkDatabase(String databaseName) { 
      return checkDatabase(context, databaseName); 
    } 

    /*** 
    * Static Method to check if database exists in application's data directory 
    * 
    * @param aContext 
    *   : application context 
    * @param databaseName 
    *   : database name 
    * @return : boolean (true if exists) 
    */ 
    private static boolean checkDatabase(Context aContext, String databaseName) { 
      SQLiteDatabase checkDB = null; 

      try { 
        String myPath = getDatabasePath(aContext, databaseName); 

        Log.i(TAG, "Trying to conntect to : " + myPath); 
        checkDB = SQLiteDatabase.openDatabase(myPath, null, 
            SQLiteDatabase.OPEN_READONLY); 
        Log.i(TAG, "Database " + databaseName + " found!"); 
        checkDB.close(); 
      } catch (SQLiteException e) { 
        Log.i(TAG, "Database " + databaseName + " does not exists!"); 

      } 

      return checkDB != null ? true : false; 
    } 

    /*** 
    * Method that returns database path in the application's data directory 
    * 
    * @param databaseName 
    *   : database name 
    * @return : complete path 
    */ 
    @SuppressWarnings("unused") 
    private String getDatabasePath(final String databaseName) { 
      return getDatabasePath(context, databaseName); 
    } 

    /*** 
    * Static Method that returns database path in the application's data 
    * directory 
    * 
    * @param aContext 
    *   : application context 
    * @param databaseName 
    *   : database name 
    * @return : complete path 
    */ 
    private static String getDatabasePath(Context aContext, String databaseName) { 
      return DB_PATH_PREFIX + aContext.getPackageName() + DB_PATH_SUFFIX 
          + databaseName; 
    } 

    public boolean executeQuery(String tableName,ContentValues values){ 
     return execQuery(tableName,values); 
    } 

    private static boolean execQuery(String tableName,ContentValues values){ 
     sqliteDb = instance.getWritableDatabase(); 
     sqliteDb.insert(tableName, null, values); 
     return true; 
    } 

    public boolean updateSQL(String tableName,String key,String value){ 
     return updateData(tableName,key,value); 
    } 

    private static boolean updateData(String tableName,String key,String value){ 
     sqliteDb = instance.getWritableDatabase(); 
     String where = ""; 
     ContentValues values = new ContentValues(); 
     values.put(key, value); 
     values.put(key, value); 
     sqliteDb.update(tableName, values, where, new String[] {"3"}); 
     return true; 
    } 

    public boolean deleteSQL(String tableName){ 
     return deleteData(tableName); 
    } 

    private static boolean deleteData(String tableName){ 
     sqliteDb = instance.getWritableDatabase(); 
     String where = ""; 
     sqliteDb.delete(tableName, where, new String[] {"5"}); 
     return true; 
    } 

    public Cursor executeSQLQuery(String query){ 
     return sqliteDb.rawQuery(query,null); 
    } 


    /** 
    * Make queries 
    * 
    */ 
} 

我有两个数据库:第一个是system.sqlite,第二个user.sqlite。 我初始化的第一个我的应用程序启动时:

dbHelper = new DataBaseHelper(this, "system.sqlite", null, 1); 
DataBaseHelper.initialize(this, "system.sqlite"); 
dbHelper.checkDatabase("system.sqlite"); 

我初始化用户的数据库以同样的方式,在我的应用程序,当用户第一次登录。 登录后,我有几个非活动课,我需要在这两个分贝的的插入一些数据:

ContentValues values = new ContentValues(); 
values.put("objectId", 75); 
values.put("objectOid", "boom"); 
values.put("serverName", "shit"); 
values.put("locale", "en_US"); 
values.put("deviceId", 45); 
dbHelper.executeQuery("users",values); 

但问题是,即使开放时,我比接近一流system.sqlite它..并尝试打开从另一个类仍然试图写入系统数据库的user.sqlite。例如:

dbHelper = new DataBaseHelper(context, "system.sqlite", null, 1); 
dbHelper.initialize(context, "system.sqlite"); 
dbHelper.getWritableDatabase(); 
//do some work 
dbHelper.close(); 

它实际上并不工作。 任何建议如何让这些东西起作用?

回答

1

为什么你没有单独的DataBaseHelper类?如UserDataBaseHelper和SystemDataBaseHelper。我知道这听起来很简单,但如果你有一个更大的项目,有两个数据库,你会把所有的数据库访问整合到一个类中吗?

0

在你的DataBaseHelper类有很多静态字段,特别是instance。例如,他们可以在initializeexecQuery方法中访问。既然你有多个数据库,我建议你摆脱DataBaseHelper中的所有单身代码,看看是否能解决问题。

+0

如果我删除所有静态字段,它会在此行引发异常:return sqliteDb.rawQuery(query,null); –

+0

您还需要修复引用静态字段的代码。 –

+0

现在我卡在这一行:return DB_PATH_PREFIX + aContext.getPackageName()+ DB_PATH_SUFFIX + databaseName; ---这是throwin'NullPointerException。 –