2012-03-09 51 views
0

我的Android應用程序出現問題。我正在使用代碼來在AsyncTask中打開SQLite數據庫。一切工作正常,但當我試圖關閉數據庫在onStop()onDestroy方法,它從來沒有關閉。SQLite數據庫從未在我的Android應用程序中關閉

代碼用於創建和打開數據庫:

公共類SQLiteDB擴展SQLiteOpenHelper {

private final Context context; 
private SQLiteDatabase sqliteDatabase = null; 

public SQLiteDB(Context context, String DBName) { 
    super(context, DBConstant.DB_NAME, null, context.getResources().getInteger(ppredota.android.navigation.view.activities.R.string.database_version)); 
    this.context = context; 
} 

public void createDB() throws IOException{ 


    if(existDB()){ 
     this.getReadableDatabase(); 
     this.close(); 
    } 
    else { 
     this.getWritableDatabase(); 
     try { 
      copyDB(); 
      this.close(); 
     } 
     catch (Exception e) { 
      throw new Error("Chyba pri kopirovani databaze"); 
     } 
    } 
} 
private boolean existDB() { 

    SQLiteDatabase checkDatabase = null; 

    try{ 
     String fullPath = DBConstant.DB_PATH + DBConstant.DB_NAME; 
     checkDatabase = SQLiteDatabase.openDatabase(fullPath, null, SQLiteDatabase.OPEN_READWRITE); 
    } 
    catch (SQLiteException sqle) { 
     Log.i("existDB()", "Databaze nelze otevrit, neexistuje"); 
    } 
    if(checkDatabase == null){ 
     Log.i("existDB", "Databaze jeste neexistuje..."); 
     return false; 
    } 
    else{ 
     Log.i("existDB", "Databaze uz existuje..."); 
     checkDatabase.close(); 
     return true; 
    } 

} 

private void copyDB() throws IOException { 

    InputStream inDBStream = context.getAssets().open(DBConstant.DB_NAME); 
    String newDBPath = DBConstant.DB_PATH + DBConstant.DB_NAME; 

    OutputStream outDBStream = new FileOutputStream(newDBPath); 
    Log.i("copyDB", "Otevren outputstream s cestou k nove databazi"); 

    byte[] buffer = new byte[1024]; 
    int length; 
    while ((length = inDBStream.read(buffer))>0){ 
     outDBStream.write(buffer, 0, length); 
    } 

    outDBStream.flush(); 
    outDBStream.close(); 
    inDBStream.close(); 
} 

public void openDB() throws SQLException { 
    String fullPath = DBConstant.DB_PATH + DBConstant.DB_NAME; 
    if(sqliteDatabase!=null){ 
     if(sqliteDatabase.isOpen()){ 
      Log.i("openDB()", "Databaze je jiz otevrena"); 
     } 
     else{ 
      sqliteDatabase = SQLiteDatabase.openDatabase(fullPath, null, SQLiteDatabase.OPEN_READONLY); 
      Log.i("openDB()", "Databaze" + sqliteDatabase.getPath() + "otevrena"); 
     } 
    } 
    else{ 
     sqliteDatabase = SQLiteDatabase.openDatabase(fullPath, null, SQLiteDatabase.OPEN_READONLY); 
     if(sqliteDatabase.isOpen()){ 
      Log.i("openDB()", "Databaze otevrena"); 
     } 

    } 
} 
@Override 
public void close() { 

    if(sqliteDatabase!=null){ 
     sqliteDatabase.close(); 
     Log.i("close()", "Databaze zavrena"); 
    } 
    super.close(); 

} 

public SQLiteDatabase getSQLiteDatabase() { 
    if(sqliteDatabase==null){ 
     Log.i("getSQLiteDatabase()","Problem, vraci sqliteDatabase = null"); 
    } 
    else{ 
     Log.i("getSQLiteDatabase()","instance sqliteDatabase vracena bez problemu"); 
    } 

    return sqliteDatabase; 

} 

AssyncTask類:

公共類OpenDatabaseTask擴展的AsyncTask {

private Context context; 
private SQLiteDB sqliteDB; 

public OpenDatabaseTask(Context context,SQLiteDB sqliteDB) { 
    this.context = context; 
    this.sqliteDB = sqliteDB; 
} 
@Override 
protected Void doInBackground(Void... params) { 
    publishProgress(); 

    try { 
     sqliteDB.createDB(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    sqliteDB.openDB(); 

    return null; 
} 
@Override 
protected void onProgressUpdate(Void...unused){ 
    Log.i(OpenDatabaseTask.class.toString(), "Spusteno vlakno"); 
} 

}

和活動(僅重要部分):

private SQLiteDB sqliteDB; 
    private SQLiteData sqliteData; 
    private OpenDatabaseTask openDatabaseTask; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.navigatemenu); 

     sqliteDB = new SQLiteDB(getApplicationContext(), sourceDatabaseName); 
     openDatabaseTask = new OpenDatabaseTask(getApplicationContext(), sqliteDB); 
     openDatabaseTask.execute(); 

    protected void onDestroy(){ 
     super.onDestroy(); 
     Log.i("onDestroy()", "Pokus o zavreni databaze"); 
      //here is the problem, database never closed 
     sqliteDB.close(); 
    } 
    protected void onStop(){ 
     super.onStop(); 
     Log.i("onStop()", "Pokus o zavreni databaze"); 
      //here is the problem, database never closed 
     sqliteDB.close(); 
    } 
    protected void onPause(){ 
     super.onPause(); 
    } 
    protected void onResume(){ 
     super.onResume(); 
     //Log.i("onResume()", "Pokus o otevreni databaze"); 
    } 
} 

所以,當我嘗試使用close()方法來關閉數據庫,sqliteDatabase總是空和數據庫永遠不會關閉。所以數據庫仍然打開並且在調用onDestroy之後發生異常。

謝謝您的時間,對不起,我的英語,我是捷克:)

+0

你確定onStop被調用? – Shellum 2012-03-09 16:13:22

+0

你確定這是一個問題嗎? – njzk2 2012-03-09 16:23:39

回答

0

只是一個猜測(假設您想要關閉的破壞)調用超級

關閉數據庫

protected void onDestroy(){ 
    // close befor super is called 
    sqliteDB.close(); 

    super.onDestroy(); 
    Log.i("onDestroy()", "Pokus o zavreni databaze"); 
    // sqliteDB.close(); // super.onDestroy may already has destroyed the DB 
} 

注:

假設數據庫只有EXIS ts並在活動可見時打開,則應在onResume()中打開數據庫並在onPause()中關閉它。

如果數據庫應該是開放的,當代碼加載到內存中的onCreate創建和的onDestroy

關閉它在你的榜樣,你在的onCreate打開它,在的onStop關閉它。 問題:活動在第二次db變爲可見時關閉。 有關詳細信息,請參見android activity documentation,並查看按鈕處的應用程序生命週期。

0

我有一個重型數據庫交互的應用程序。我沒有用戶幫手。我的數據庫被打開了很多次,在UI線程和後臺線程中,但從未關閉過。目前爲止沒有問題,不知道這是否是正確的方法...

相關問題