ListView SimpleCursorAdapter обновляется асинхронно - PullRequest
0 голосов
/ 02 января 2012

У меня есть класс, который имеет SimpleCursorAdapter в качестве поля.Этот адаптер используется для представления списка, который имеет viewBinder.

У меня есть асинхронная задача, которая запускает запись в базу данных, а затем обновляет курсор.

При тестировании, если я слишком быстро нажимаю на кнопку, которая запускает асинхронный процесс, я получаю сообщение об ошибке:

java.lang.RuntimeException: An error occured while executing doInBackground()
...
Caused by: java.lang.IllegalStateException: database [path_to_my_db] already closed

Код работает отлично - если ... пользователь не нажимает кнопкуКнопка «Сохранить» быстро по очереди ... Я новичок во всем этом, поэтому любой ввод будет принята с благодарностью!

Вот урезанная версия того, что я пытаюсь сделать:

public class MyActivity extends Activity {

    private DatabaseConnector connector; // this is my class for managing SQLite
    private SimpleCursorAdapter adapter; 

    ....

    @Override
    public void onCreate(Bundle savedInstanceState){

        ...

        myListView = (ListView)findViewById(R.id.my_list_view);
        String[] = new String{"This", "part", "is", "working"};
        int[] to = new int[] {1,2,3,4}; // again, this is working...

        adapter = new SimpleCursorAdapter(this, R.layout.my_list_item_row, null, from, to);
        adapter.setViewBinder(new ViewBinder(){
            ... // this is all working
            ... // the viewBinder is for custom date formatting... again, all works
        });

        myListView.setAdapter(adapter);

    }

    private class MyAsyncTask extends AsyncTask<Context, Void, ExerciseInstanceViewModel>{

        MyViewModel vm; // this viewModel has a cursor member...

        public MyAsyncTask([variables-all-working]){

        }

        @Override
        protected MyViewModel doInBackground(Context... params) {

            connector = new DatabaseConnector(MyActivity.this);
            connector.open(); // TODO: Getting 'did not close database error here...'

            vm = connector.runMethodThatIncludesCursorInReturnType([input-paramters-working]);

            return vm;

            }

        // use the cursor returned from the doInBackground method 
        @Override 
        protected void onPostExecute(MyViewModel result){

            super.onPostExecute(result);

            // set instance fields in outer class...;
            // set textView, progressBar, etc..

            if (result.MyCursor != null)
            {
                adapter.changeCursor(result.MyCursor);
            }

            connector.close(); // aren't i closing the db here??? 
                        [Code to reload page with next detail items]
        }

    } 
}

Ответы [ 2 ]

0 голосов
/ 05 января 2012

Сделать обертку вокруг разъема, синхронизированную и как одиночную. Я полагаю, что вы обращаетесь к базе данных одновременно. Это раздетая версия одного из моих:

(я переопределяю базу данных getWriteable, чтобы включить внешние ключи, но вам этого не нужно)

     public class DatabaseHelper extends SQLiteOpenHelper {

    private static final String DATABASE_NAME = "myDatabase";
    private static final int DATABASE_VERSION = 1;
    private Context context = null;
    private static DatabaseHelper instance = null;

    public static synchronized DatabaseHelper getInstance(Context context){

        if (instance == null){
            instance = new DatabaseHelper(context, null);           
        }

        return instance;
    }

    @Override
    public synchronized SQLiteDatabase getWritableDatabase() {
        SQLiteDatabase db = super.getWritableDatabase();
        db.execSQL("PRAGMA foreign_keys=ON;");
        return db;
    }

    private DatabaseHelper(Context context, CursorFactory factory) {
        super(context, DATABASE_NAME, factory, DATABASE_VERSION);
        this.context = context;
    }


}
0 голосов
/ 02 января 2012

if (result.MyCursor! = Null) { adapter.changeCursor (result.MyCursor); }

}

}

connector.close (); }

попробуй это.

...