2012-12-17 37 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

相关问题