2013-02-13 154 views
1

我正在將數據庫文件從我的資產文件夾複製到安裝時的數據庫文件夾。我有一個名爲firstRun的默認值爲true的共享首選項。如果這是真的,那麼我複製數據庫文件並將firstRun值設置爲false。緊接着這個過程之後,我查詢數據庫表中的一些數據。在較老的Android版本(2.1)上發生SQLite異常(無此表)並且應用程序崩潰,在Android 4.2.1上,dbHelper記錄相同的消息,但繼續運行並從剛剛找不到的表中返回值。使用早期的Android版本,如果我再次啓動應用程序,則會找到數據庫表並且所有操作都能正常進行。在應用程序崩潰後,我可以檢查複製的數據庫,並且存在表和行。這似乎與表格真正不存在的其他問題不同,因爲我可以看到它們的確存在。我不知道這是否是某種同步問題,即在複製過程後該表不存在,而是在某個過程完成時發生。據我所知,這不是異步完成的,所以我不知道爲什麼。Android SQLite數據庫表在創建後不存在

下面是一些代碼來說明問題:

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); 
boolean firstRun = prefs.getBoolean(getString(R.string.first_time_run), true); 

if (firstRun) { 
    SharedPreferences.Editor edit = prefs.edit(); 
    edit.putBoolean(getString(R.string.first_time_run), Boolean.FALSE); 
    edit.commit(); 

    try { 
     dbHelper.createDatabase(); 
    } catch (IOException ioe) { 
     ioe.printStackTrace(); 
    } 
} 
// This method will fire an exception the first time the app is run - no such table 
Bundle metaData = dbHelper.fetchAppMetaData(); 
this.appTitle = metaData.getString("app_title"); 
this.normalId = Integer.parseInt(metaData.getString("normal_id")); 

的fetchAppMetaData方法是一個基本的sqlite.query:

Bundle metaData = new Bundle(); 
Cursor dbCursor = null; 
SQLiteDatabase database = getReadableDatabase(); 
String[] cols = new String[] {"app_title", "normal_id"}; 
dbCursor = database.query(true, TBL_METADATA, cols, null, null, null, null, null, null); 

if (dbCursor != null) { 
     dbCursor.moveToFirst(); 

最終將返回一個包。

數據庫創建方法是:

//Open the local db as the input stream 
InputStream dbFromAssets = myContext.getAssets().open(DB_NAME); 

// Path to the just created empty db 
String outFileName = DB_PATH + DB_NAME; 

// Check that the directory now exists 
File f = new File(DB_PATH); 

if (!f.exists()) { 
    f.mkdir(); 
} 

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

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

// Close the streams - don't cross them! 
appDatabase.flush(); 
appDatabase.close(); 
dbFromAssets.close(); 

肯做任何想法不勝感激吧。

+0

http://stackoverflow.com/questions/9109438/how-to-use-an-existing-database-with-an-android-application/9109728#9109728 – 2013-02-13 12:48:14

回答

0

對我來說,解決辦法是關閉dbHelper在創建數據庫後之前,我再次嘗試使用它。

例如:

try { 
    dbHelper.createDatabase(); 
} catch (Exception e) { 
} 
dbHelper.close(); 
dbHelper.fetchAppMetaData(); 

希望這可以幫助其他人。

0

下面是從工作代碼中剪切和粘貼。每次應用程序加載時,我都會在啓動MainActivity時使用它。經過測試,與2.3版本的工作 - 4.2:

這裏是我使用的代碼沒有檢查:

try 
    {   
     String destPath = "/data/data/" + getPackageName() + "/databases/(...your db...)"; 

     File f = new File(destPath); 
     File c = new File("/data/data/" + getPackageName() + "/databases/"); 

     // ---if directory doesn't exist then create it--- 
     if (!c.exists()) 
     { 
      c.mkdir(); 
     } 

     // ---if db file doesn't exist then create it--- 
     if (!f.exists()) 
     { 
      CopyDB(getBaseContext().getAssets().open("...name of db from assets foleder..."), new FileOutputStream(destPath)); 
     } 
    } 
    catch (FileNotFoundException e) 
    {   
     e.printStackTrace(); 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 

這裏是我使用的是不復制的代碼,如果沒有找到:

public void CopyDB(InputStream inputStream, OutputStream outputStream) throws IOException 
{ 
    //---copy 1K bytes at a time--- 
    byte[] buffer = new byte[1024]; 
    int length; 
    while ((length = inputStream.read(buffer)) > 0) 
    { 
     outputStream.write(buffer, 0, length); 
    } 

    inputStream.close(); 
    outputStream.close(); 
} 

希望這是有希望的......

+0

感謝您花時間回覆。這正是我所做的,所以不幸的是它並沒有幫助我。 – voncox 2013-02-13 12:46:34

+0

使用此我從來沒有遇到與未找到數據庫的問題。我只是簡單地粘貼一個工作示例,以便您可以嘗試一下,看看是否仍然有相同的錯誤,如果不是那麼好,如果是,那麼您又回到了現在的位置......不會傷害到嘗試一下... – cking24343 2013-02-13 12:58:51