CursorAdapter:当我使用changeCursor()时,事件setOnItemClickListener()开始崩溃

时间:2013-02-03 15:20:31

标签: android android-cursoradapter

我正在更新与我已扩展的CursorAdapter链接的ListView。

当我收到通知时,我升级了相应的表sqlite。然后使用curosor从表中恢复所有记录,并使用changeCursor()更改ListView。

不幸的是,事件setOnItemClickListener可能会以开始崩溃,因为他使用了对光标的旧引用

以下代码在AsyncTask(由Activity X调用)结束时执行,该数据将数据保存到表sqlite并将光标设置为listview。最后在listview中添加一个事件。

final Cursor cursor = dao.getAllRubrica();
        dao.close();

        CustomCursorAdapter provaAdapter = new CustomCursorAdapter(applicationContext,cursor,0);
        //cursor.close();

        ListView rubricaListView = (ListView) controlPanelActivity.findViewById(R.id.rubricaListView);


        rubricaListView.setAdapter(provaAdapter);
        controlPanelActivity.setRubricaListView(rubricaListView);

        rubricaListView.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                cursor.moveToPosition(position);
                String target_email = cursor.getString(cursor.getColumnIndexOrThrow(DatabaseHelper.TABLE_RUBRICA_DESTINATARIO));

                String userEmail = controlPanelActivity.loadSharPrefs();
                if(userEmail!=null && !userEmail.isEmpty()){
                    // ....
                }
            }
        });

当Activity X收到通知时,会执行以下代码,因此我获取listview的光标并使用新光标进行更改。现在事件setOnItemClickListener开始崩溃了!

CustomCursorAdapter a = (CustomCursorAdapter) rubricaListView.getAdapter();
    a.changeCursor(newCursor);

这里的错误(第一行很重要):

02-03 14:54:48.791: E/AndroidRuntime(1672): FATAL EXCEPTION: main 02-03 14:54:48.791: E/AndroidRuntime(1672): java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteQuery: SELECT _id, destinatario, inizio_conversazione, nick_dest, flag_new_mess FROM rubrica 02-03 14:54:48.791: E/AndroidRuntime(1672): at Android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55) 02-03 14:54:48.791: E/AndroidRuntime(1672):   at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:58) 

02-03 14:54:48.791:E / AndroidRuntime(1672):在android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:151) 02-03 14:54:48.791:E / AndroidRuntime(1672):在android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:124) 02-03 14:54:48.791:E / AndroidRuntime(1672):在android.database.AbstractCursor.moveToPosition(AbstractCursor.java:213) 02-03 14:54:48.791:E / AndroidRuntime(1672):at com.app.task.GetRubricaTask $ 1.onItemClick(GetRubricaTask.java:211) 02-03 14:54:48.791:E / AndroidRuntime(1672):在android.widget.AdapterView.performItemClick(AdapterView.java:298) 02-03 14:54:48.791:E / AndroidRuntime(1672):在android.widget.AbsListView.performItemClick(AbsListView.java:1086) 02-03 14:54:48.791:E / AndroidRuntime(1672):在android.widget.AbsListView $ PerformClick.run(AbsListView.java:2855) 02-03 14:54:48.791:E / AndroidRuntime(1672):在android.widget.AbsListView $ 1.run(AbsListView.java:3529) 02-03 14:54:48.791:E / AndroidRuntime(1672):在android.os.Handler.handleCallback(Handler.java:615) 02-03 14:54:48.791:E / AndroidRuntime(1672):在android.os.Handler.dispatchMessage(Handler.java:92) 02-03 14:54:48.791:E / AndroidRuntime(1672):在android.os.Looper.loop(Looper.java:137) 02-03 14:54:48.791:E / AndroidRuntime(1672):在android.app.ActivityThread.main(ActivityThread.java:4745) 02-03 14:54:48.791:E / AndroidRuntime(1672):at java.lang.reflect.Method.invokeNative(Native Method) 02-03 14:54:48.791:E / AndroidRuntime(1672):at java.lang.reflect.Method.invoke(Method.java:511) 02-03 14:54:48.791:E / AndroidRuntime(1672):at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:786) 02-03 14:54:48.791:E / AndroidRuntime(1672):at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 02-03 14:54:48.791:E / AndroidRuntime(1672):at dalvik.system.NativeStart.main(Native Method)

如何在致电changeCursor()后继续投放活动?我需要在AsyncTask中更改一些内容吗?

2 个答案:

答案 0 :(得分:0)

你可以试试这个:

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
            // CursorAdapter returns a cursor at the correct position for getItem(), or null
            // if it cannot seek to that position.
            Cursor cursor = (Cursor) adapterView.getItemAtPosition(position);
            if (cursor != null) {
                //Do something with cursor
            }
        }
    });

答案 1 :(得分:0)

  

java.lang.IllegalStateException:尝试重新打开已经关闭的   object:SQLiteQuery:SELECT _id,destinatario,inizio_conversazione,   nick_dest,flag_new_mess FROM rubrica

此代码表示您在光标可以从中检索所有数据之前关闭数据库,因此注释掉该行并且它将正常工作:

dao.close();

而是在onDestroy或onStop上关闭光标和数据库的连接,并分别在onCreate或onRestart上再次打开。 ListView从段中的适配器获取数据以最小化资源负载,当用户向下滚动列表时,它们从游标请求数据,因此尝试在活动生命周期的最后关闭数据库和光标。