StaleDataException: доступ к закрытому курсору - PullRequest
5 голосов
/ 09 июня 2010

В моем приложении, после достаточного количества нажатий, я получаю эту ошибку:

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.

1 Ответ

6 голосов
/ 09 июня 2010

Я полагаю, что когда он признан недействительным, вы хотите вызвать requery() на курсоре. Вы могли бы сделать это в onInvalidated().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...