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