2012-12-17 79 views
1

我的應用程序包含許多活動,到目前爲止,在活動之間移動時訪問數據庫時沒有問題。然而在最後一個listActivity(LocationActivity)中,我在每個listView項目上都有一個嵌入式按鈕。當在活動之間切換時訪問SQLite數據庫時出現異常

當點擊其中一個按鈕時,它會將您發送到SpecificationEdit.java,其中用戶將該規範輸入到該列表視圖項目(損壞的組件)的某些EditText字段中,但是當您單擊保存時會崩潰並出現以下錯誤消息(注意數據保存到數據庫OK):

java.lang.RuntimeException: Unable to resume activity blah blah 
Exception: trying to requery an already closed cursor blah blah 

這裏是listActivity類:

public class LocationActivity extends ListActivity { 

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

    rmDbHelper = new RMDbAdapter(this); 
    rmDbHelper.open(); 
    getIntents(); 
    setUpViews(); 
    setAdapter();    
    setTextChangedListeners(); 
} 

protected void onResume(){ 
    super.onResume(); 
    final Cursor locationCursor = (Cursor) rmDbHelper.fetchLocationsForRun(runId); 
    startManagingCursor(locationCursor); 
    locationCursorSize = locationCursor.getCount(); 
    setAdapter(); 
    setTextChangedListeners(); 
} 

這裏是本次活動的位在哪裏向您發送SpecificationEdit.java

private void startComponentEdit() { 
    Intent i = new Intent(LocationActivity.this, SpecificationEdit.class); 
    i.putExtra("Intent_InspectionID", inspectionId); 
    i.putExtra("Intent_AreaID", areaId); 
    i.putExtra("Intent_RunID", runId); 
    i.putExtra("Intent_LocationID", locationId); 
    i.putExtra("Intent_Ref", locationRef); 
    i.putExtra("Intent_DamagedComponentID", damagedComponentId); 
    startActivityForResult(i, ACTIVITY_CREATE); 

} 

這裏是OnCreate中在SpecificationEdit.java:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    rmDbHelper = new RMDbAdapter(this); 
    rmDbHelper.open(); 
    Intent i = getIntent(); 
    inspectionId = i.getLongExtra("Intent_InspectionID", -1); 
    areaId = i.getLongExtra("Intent_AreaID", -1); 
    runId = i.getLongExtra("Intent_RunID", -1); 
    locationId = i.getLongExtra("Intent_LocationID", -1); 
    damagedComponentId = i.getLongExtra("Intent_DamagedComponentID", -1); 
    setContentView(R.layout.edit_specification); 
    setUpViews(); 
    populateFields(); 
    fillSpinner(); 
    setListeners(); 
} 

隨着其觸發代碼位當您單擊保存按鈕:

protected void saveDamagedComponentSpec() { 

    String manufacturer = ((Cursor)manufacturerSpinner.getSelectedItem()).getString(1).toString(); 
    String text1 = specEditText1.getText().toString(); 
    String text2 = specEditText2.getText().toString(); 
    String text3 = specEditText3.getText().toString(); 
    String text4 = specEditText4.getText().toString(); 
    String notes_spec = specEditTextNotes.getText().toString(); 

    rmDbHelper.saveDamagedComponentSpec(damagedComponentId, manufacturer, text1, text2, text3, text4, notes_spec);  

    if ("Yes".equals(specSaved)){ 
     Toast.makeText(getApplicationContext(), "Component specification updated", 
      Toast.LENGTH_SHORT).show(); 
    } 

    else { 
     Toast.makeText(getApplicationContext(), "Component specification added", 
       Toast.LENGTH_SHORT).show(); 

    } 

    finish(); 
} 

最後,這裏是代碼在我的數據庫幫助類:

//Constructor - takes the context to allow the database to be opened/created 
public RMDbAdapter(Context ctx) { 
    this.mCtx = ctx; 
} 

/** 
* Open the rm database. If it cannot be opened, try to create a new 
* instance of the database. If it cannot be created, throw an exception to 
* signal the failure 
* 
* @return this (self reference, allowing this to be chained in an 
*   Initialisation call) 
* @throws SQLException if the database could be neither opened or created 
*/ 
public RMDbAdapter open() throws SQLException { 
    rmDbHelper = new DatabaseHelper(mCtx); 
    rmDb = rmDbHelper.getWritableDatabase(); 
    return this; 
} 


public void close() { 
    rmDbHelper.close(); 
} 

w奇怪的是,你可以點擊listView項目(實際項目不是嵌入項目)或按鈕'添加新組件',這會將你帶到具有非常類似接口的另一個活動ComponentEdit.java(添加一個組件到清單)作爲SpecificationEdit,但它完成時不會崩潰的應用程序。

我看不到兩個活動之間有任何主要區別,但當您返回到LocationActivity而另一個沒有時,您會看到此錯誤。

我剛剛嘗試刪除onResume,這沒有什麼區別..打這個磚牆,這是在推動我堅果。

我應該補充說,它在我的模擬器上工作正常,但是當我在手機上測試它時會崩潰(HTC One S)。很奇怪..

+0

你手動關閉locationCursor? – nandeesh

+0

感謝快速反應nandeesh。我更新了我的代碼,這樣做,但如果你正在使用startManagingCursor你永遠不應該關閉遊標這並沒有什麼差別.. – Scamparelli

+0

,活動將採取照顧它 – nandeesh

回答

0

權,發現問題(現貨明顯的錯誤):

Cursor componentsCursor = (Cursor) rmDbHelper.fetchDamagedComponentSpecForInspection(inspectionId, componentType); 
    startManagingCursor(componentsCursor); 

    Intent i = new Intent(this, SpecificationEdit.class); 
    i.putExtra("Intent_InspectionID", inspectionId); 
    i.putExtra("Intent_AreaID", areaId); 
    i.putExtra("Intent_RunID", runId); 
    i.putExtra("Intent_LocationID", locationId); 
    i.putExtra("Intent_Ref", locationRef); 
    i.putExtra("Intent_DamagedComponentID", damagedComponentId); 
    startActivityForResult(i, ACTIVITY_CREATE); 

    componentsCursor.close(); 

所以它不是componentsCursor.close之前在此留下了明顯的(我有一些阻擋了代碼() ),但是當我完成了specifcationEdit.class時,我想它返回到這個活動並嘗試關閉componentsCursor但顯然失敗。

愚蠢的是,我實際上還沒有得到這個光標做任何事情!衛生署!

只是爲了一些額外的建議/ whittering;我的應用程序基本上與Google notePad示例不同,因爲我實際上並沒有像使用startActivityForResult那樣使用它(事實上,現在我更好地理解它,因爲我將數據輸入到數據庫時仍然只用startActivity)在編輯活動中,在那裏然後(而不是通過意圖傳遞這些信息,然後在返回到上一個活動時添加信息)。

我覺得這在我的代碼領域更合乎邏輯,但是有關此方法的任何反饋?

0

不要忘了打電話給rmDbHelper.close();之前啓動另一項活動

+0

感謝您對letroll的響應,但即使在完成SpecificationEdit.java並返回到LocationActivity之前關閉數據庫,它也沒有任何區別。但是,我離開之前的活動時沒有關閉它,並且當我從一個活動返回而沒有從另一個活動返回時,它就可以正常工作。 – Scamparelli

+0

您是否嘗試在startComponentEdit()中添加rmDbHelper.close?並在SpecificationEdit的onDestroy中? – letroll

相關問題