ListView SimpleCursorAdapter异步更新

时间:2012-01-02 05:58:48

标签: android sqlite android-asynctask simplecursoradapter

我有一个将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 :(得分:0)

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

}

}

connector.close(); }

试试这个。

答案 1 :(得分:0)

围绕连接器创建一个包装器,同步并作为单例。我相信你是在同一时间访问数据库。这是我自己的一个剥离版本:

(我重写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;
    }


}