我的应用程序包含许多活动,到目前为止,在活动之间移动时访问数据库没有任何问题。但是在最后一个listActivity(LocationActivity)上,我在每个listView项上都有一个嵌入式按钮。
当单击其中一个按钮时,它会将您发送到SpecificationEdit.java,其中用户将specfication输入到该listView项目(损坏的组件)的某些EditText字段中,但是当您单击Save it crashes时会出现以下错误消息(注意数据保存到数据库确定):
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);
}
这是SpecificationEdit.java中的OnCreate:
@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();
}
奇怪的是,你可以点击listView项目之一(实际项目不是嵌入项目)或按钮'添加新组件',这将发送到另一个具有非常相似接口的活动ComponentEdit.java(将一个组件添加到列表中)作为SpecificationEdit但是当它完成时不会使应用程序崩溃。
我看不出这两个活动之间有什么重大区别,但是当你返回到LocationActivity时,有一个是因为这个错误而崩溃,而另一个则没有。
我刚尝试删除onResume,这没什么区别。用这个打砖墙,这让我疯了。
我应该补充说它在我的模拟器上工作正常,但是当我在手机上测试它时崩溃(HTC One S)。很奇怪..
答案 0 :(得分:0)
不要忘记调用rmDbHelper.close();在开始另一项活动之前
答案 1 :(得分: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()之前留下了一些阻塞的代码),但是当我完成了SpeccationEdit.class时,我猜它会返回到这个活动并尝试关闭componentsCursor但是显然失败了。
愚蠢的是,我还没有让这个光标做任何事情!卫生署!
只是为了一些额外的建议/ whittering;我的应用程序与Google notePad示例基本不同,因为我实际上并没有像他们那样使用startActivityForResult(事实上现在我理解它更好,我将用startActivity替换所有这些)因为我将数据输入到数据库中在编辑活动中,然后(而不是通过意图传递此信息,然后在返回上一个活动时添加。)
我发现这在我的代码领域更合乎逻辑,但是对这种方法的反馈是什么?