1

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

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

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

以下代码在 AsyncTask(由 Activity X 调用)的末尾执行,将数据保存到表 sqlite 并将光标设置为列表视图。最后向列表视图添加一个事件。

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 收到通知时执行,因此我获取列表视图的光标并使用新光标进行更改。现在事件 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): 在 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): 在 java.lang.reflect.Method.invokeNative(Native Method) 02-03 14:54:48.791: E/AndroidRuntime(1672): 在 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): 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 02-03 14:54:48.791: E/AndroidRuntime(1672): 在 dalvik.system.NativeStart.main (本机方法)

调用后如何继续运行事件changeCursor()?我需要更改 AsyncTask 中的某些内容吗?

4

2 回答 2

0

java.lang.IllegalStateException:尝试重新打开一个已经关闭的对象:SQLiteQuery:SELECT _id、destinatario、inizio_conversazione、nick_dest、flag_new_mess FROM rubrica

此代码意味着您在 cursor 可以从中检索所有数据之前关闭数据库,因此注释掉这一行,它将正常工作:

dao.close();

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

于 2017-05-02T06:46:46.493 回答
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
            }
        }
    });
于 2017-04-22T07:59:15.067 回答