2012-04-03 55 views
2

在前面的問題中,我建議我不需要維護數據庫,因爲設備因使用本地數據庫而旋轉。旋轉設備時發生崩潰 - 生命週期問題

我認爲我至少可以維護我的列表的數據源。我在嘗試執行此操作時遇到了問題,因爲我收到錯誤,說沒有在數據庫上調用close()。儘管我在onDestroy中調用close。

任何人都可以看到我在哪裏錯了嗎?我只想通過維護數據以在旋轉設備後重新填充列表來改善用戶體驗。

是困惑我的另一件事是我的日誌報表中按以下順序出來:

  • 的onCreate航班
  • 第一設置
  • 重複使用的數據源
  • 破壞活性

我希望在重新使用數據源之前銷燬活動發生。

package com.testing.flights; 

import android.app.ListActivity; 
import android.database.Cursor; 
import android.database.sqlite.SQLiteDatabase; 
import android.os.Bundle; 
import android.provider.BaseColumns; 
import android.util.Log; 
import android.widget.SimpleCursorAdapter; 

public class FlightListActivity extends ListActivity { 

private SQLiteDatabase database; 
private String fields[] = {BaseColumns._ID, "name", "flights", "distance"}; 
private SimpleCursorAdapter datasource; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    Log.v(ACTIVITY_SERVICE, "onCreate flights"); 

    datasource = (SimpleCursorAdapter) getLastNonConfigurationInstance(); 

    if (datasource == null) { 
     database = getData(); 
     datasource = getCursor(); 
     Log.v(ACTIVITY_SERVICE, "first setup"); 
    } 

    setListAdapter(datasource); 
} 

protected SQLiteDatabase getData() { 
    DataBaseHelper myDbHelper = new DataBaseHelper(this.getApplicationContext()); 
    return myDbHelper.openDataBase(); 
} 

protected CustomCursorAdapter getCursor() { 
    Cursor data = database.query("pilots", fields, null, null, null, null, null); 
    final CustomCursorAdapter mysource = new CustomCursorAdapter(this, R.layout.row, data, fields, new int[] { R.id.id, R.id.name, R.id.flights, R.id.distance }); 
    return mysource; 
} 

@Override 
public Object onRetainNonConfigurationInstance() { 
    Log.v(ACTIVITY_SERVICE, "reusing datasource"); 
    final SimpleCursorAdapter myData = datasource; 
    return myData; 
} 

@Override 
protected void onDestroy() { 
    Log.v(ACTIVITY_SERVICE, "destroying activity"); 
    database.close(); 
    super.onDestroy(); 
} 

} 

LogCat:

04-03 16:22:55.900: E/SQLiteDatabase(1860): close() was never explicitly called on database '/data/data/com.testing.flights/databases/club' 
+0

當你有任何錯誤總是發表您的logcat – 2012-04-03 15:34:48

+0

@Samir - 我已經添加了錯誤 – Neil 2012-04-03 15:36:47

+0

尼爾,看看官方Android開發者博客,有一個整體上張貼。 – 2012-04-03 15:42:49

回答

1

我相信所發生的事情是,OS是優先考慮的新活動的創建過舊的破壞。由於onDestroy無法保證運行(可能會被終止),因此通常在onResume()中打開數據庫,並在onPause()方法中自行清理。 (onPause不會被殺死,至少在honeycomb +中)。由於你現在擁有的東西,新的活動正試圖打開一個已經打開的數據庫(這是我的猜測)。沒有試圖保留這樣的遊標,我不是100%,這將解決您的問題,但使用生命週期的這一部分是非視圖設置類型的事情的正常情況。

+0

您的回答促使我更多地關注生命週期以及如何正確地做事 – Neil 2012-04-03 17:13:55

0

在manifeast文件中添加以下行的FlightListActivity

android:configChanges="keyboardHidden|orientation" 

現在就來試試,我認爲應用程序不會崩潰,因爲通過使用設備的旋轉從橫向到縱向上線,反之亦然不會調用再次創建方法。

+0

雖然這確實奏效,但我讀過的文檔卻說它應該作爲最後的手段使用。 – Neil 2012-04-03 17:11:00

0
@Override 
    public void onConfigurationChanged(Configuration newConfig) { 
     // TODO Auto-generated method stub 

     super.onConfigurationChanged(newConfig); 

      if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { 

      } else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { 

      } 

    } 
+0

我決定通過正確使用生命週期方法來處理這個問題 – Neil 2012-04-03 17:11:45