5

在我的应用程序中,经过足够的点击,我得到了这个错误:

06-08 19:47:59.967: ERROR/AndroidRuntime(2429): java.lang.RuntimeException: Unable to pause activity {com.MYAPP.app/com.MYAPP.app.MainActivity}: android.database.StaleDataException: Access closed cursor

我拥有的是一个选项卡活动(我的 MainActivity),它有一个 ListActivity 作为每个选项卡的内容。在每个 ListActivity 的 onCreate 中,我得到一个光标,表示要在该列表中显示的数据。

每个列表的 onListItemClick 还会创建另一个活动,因此单击列表中的项目将在新屏幕中显示有关该项目的更多信息。这是不一致的,但是在足够多地点击这些新活动,或者从一个新活动返回到 ListView 之后,程序崩溃了。

在寻找解决我的问题的方法时,我确实偶然发现了 registerDataSetObserver,但它似乎并不是完整的答案。我也很难找到关于它的文档,所以我不确定我是否完全理解它。我有一个自定义 ListAdapter,我的 ListViews 都使用它,并且在那里的游标上调用了 registerDataSetObservers。

我已从我的 ListActivities 之一和我的自定义 ListAdapter 类中附加了相关代码。


列表活动。我有其中两个,几乎相同,只是它们都有从不同的数据库查询创建的不同游标:

import com.MYAPP.app.listmanager.DeviceListAdapter;

public class AllSensorsActivity extends ListActivity{

    private DeviceListAdapter AllList;
    private DbManager db;
    protected Cursor AllCur;
    protected Cursor AllSensors;


    private static final String TAG = "AllSensorsActivity";                     

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        Log.e(TAG, "Calling All onCreate");

        db = new DbManager(this);
        db.open();

        AllCur = db.fetchAllDevices();
        startManagingCursor(AllCur);                                            
        AllSensors = db.fetchAllSensors();
        startManagingCursor(AllSensors);


        AllList = new DeviceListAdapter(this, AllCur, AllSensors);
        setListAdapter(AllList);
    }


    @Override
    protected void onListItemClick(ListView l, View v, int position, long id){

        String device_name = (String) ((DeviceListAdapter)getListAdapter()).getItem(position);
        String sensor_string = ((DeviceListAdapter)getListAdapter()).getSensors(id);

        Intent i = new Intent(this, SensorActivity.class);
        Bundle bundle = new Bundle();
        bundle.putString("NAME", device_name);
        i.putExtras(bundle);
        bundle.putString("SENSORS", sensor_string);
        i.putExtras(bundle);
        this.startActivity(i);

    }

自定义 ListAdapter:

public class DeviceListAdapter extends BaseAdapter {

    private static final String TAG = "DeviceListAdapter";

    private Context mContext;
    private Cursor mSensors;
    private Cursor mDevices; 
    protected MyDataSetObserver sensors_observer;
    protected MyDataSetObserver devices_observer;

    public DeviceListAdapter(Context context, Cursor devices, Cursor sensors){  
        mContext = context;
        mDevices = devices;
        mSensors = sensors;

        sensors_observer = new MyDataSetObserver();
        mSensors.registerDataSetObserver(sensors_observer);
        devices_observer = new MyDataSetObserver();
        mDevices.registerDataSetObserver(devices_observer);
    }
    // ... more functions and stuff that are not relevant go down here...
}

private class MyDataSetObserver extends DataSetObserver {
    public void onChanged(){
        Log.e(TAG, "CHANGED CURSOR!");
    }
    public void onInvalidated(){
        Log.e(TAG, "INVALIDATED CURSOR!");
    }
}

我应该让 MyDataSetObserver 捕获异常并继续吗?如果可能的话,我想要一个比这更强大的解决方案。或者有没有其他方法可以重新安排我的程序,这样 staleDataException 就不会发生(经常)?我相信它正在发生,因为我正在我的 onListItemClick 中启动新活动。

4

1 回答 1

6

我相信当它失效时你想调用requery()光标。你可以在onInvalidated().

于 2010-06-08T21:06:05.347 回答