В моем приложении, после достаточного нажатия вокруг, я получаю эту ошибку:
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 как содержание для каждой вкладки. В onCreate для каждого ListActivity я получаю курсор, который представляет данные, которые будут отображены в том списке.
onListItemClick для каждого списка также создает другое действие, так нажатие на объект в списке покажет больше информации о том объекте на новом экране. Это непоследовательно, но после достаточного нажатия в эти новые операции или возвращение к ListView от нового действия, катастрофических отказов программы.
В поиске вокруг решения моей проблемы, я действительно натыкался на registerDataSetObserver, но это, кажется, не целый ответ. Я также испытываю затруднения при нахождении документации относительно него, таким образом, я не уверен, что полностью понимаю это. У меня есть пользовательский ListAdapter, что оба моих ListViews используют и назвали registerDataSetObservers на курсорах там.
Я присоединил соответствующие нормы от одного из моих ListActivities и от моего пользовательского класса ListAdapter.
ListActivity. У меня есть два из них, почти идентичных, кроме ним обоим создали различные курсоры из различных запросов базы данных:
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.
Я полагаю, что когда он становится недействительным, вы хотите вызвать requery()
для курсора. Возможно, это можно сделать в onInvalidated()
.