1

我的应用程序包含许多活动,到目前为止,在活动之间移动时访问数据库没有问题。但是在最后一个 listActivity (LocationActivity) 上,我在每个 listView 项目上都有一个嵌入式按钮。

单击其中一个按钮时,它会将您发送到 SpecificationEdit.java,用户在其中将规范输入到该 listView 项(损坏的组件)的某些 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);

}

这是 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)上测试时崩溃。很奇怪..

4

2 回答 2

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 但显然失败了。

愚蠢的是,我实际上还没有让这个光标做任何事情!嗬!

只是为了一些额外的建议/发白;我的应用程序与谷歌记事本示例根本不同,因为我实际上并没有像他们那样使用 startActivityForResult(事实上,现在我更好地理解了,我将用 startActivity 替换所有这些),因为我将数据输入到数据库中同时仍然在编辑活动上,然后(而不是通过意图传递此信息,然后在您返回上一个活动时添加。

我发现这在我的代码领域更合乎逻辑,但是对这种方法有任何反馈吗?

于 2012-12-18T15:34:14.713 回答
0

不要忘记调用 rmDbHelper.close(); 在开始另一项活动之前

于 2012-12-17T17:02:49.470 回答