IllegalStateException:尝试重新打开已关闭的对象

时间:2014-07-15 15:43:42

标签: android android-listview simplecursoradapter

我在保留的Cursor中使用DialogFragment。创建Cursor视图后AsyncTask加载DialogFragmentDialogFragment被销毁后关闭Cursor。然后SimpleCursorAdapter将被移交给ListView

目前我正在测试Froyo模拟器。问题是,当我在ListView - >上快速滚动时驳回了对话 - >再次打开它 - >应用程序崩溃(请参阅下面的日志)。

我在手机上遇到类似的问题,在关闭对话框并再次打开对话框之前等待07-15 22:09:45.402: E/AndroidRuntime(494): FATAL EXCEPTION: main 07-15 22:09:45.402: E/AndroidRuntime(494): java.lang.IllegalStateException: attempt to re-open an already-closed object: android.database.sqlite.SQLiteQuery (mSql = my query) 07-15 22:09:45.402: E/AndroidRuntime(494): at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:34) 07-15 22:09:45.402: E/AndroidRuntime(494): at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:64) 07-15 22:09:45.402: E/AndroidRuntime(494): at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:283) 07-15 22:09:45.402: E/AndroidRuntime(494): at android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:255) 07-15 22:09:45.402: E/AndroidRuntime(494): at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:188) 07-15 22:09:45.402: E/AndroidRuntime(494): at android.support.v4.widget.CursorAdapter.getView(CursorAdapter.java:247) 07-15 22:09:45.402: E/AndroidRuntime(494): at android.widget.AbsListView.obtainView(AbsListView.java:1294) 07-15 22:09:45.402: E/AndroidRuntime(494): at android.widget.ListView.makeAndAddView(ListView.java:1727) 07-15 22:09:45.402: E/AndroidRuntime(494): at android.widget.ListView.fillDown(ListView.java:652) 07-15 22:09:45.402: E/AndroidRuntime(494): at android.widget.ListView.fillGap(ListView.java:623) 07-15 22:09:45.402: E/AndroidRuntime(494): at android.widget.AbsListView.trackMotionScroll(AbsListView.java:2944) 07-15 22:09:45.402: E/AndroidRuntime(494): at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:2485) 07-15 22:09:45.402: E/AndroidRuntime(494): at android.os.Handler.handleCallback(Handler.java:587) 07-15 22:09:45.402: E/AndroidRuntime(494): at android.os.Handler.dispatchMessage(Handler.java:92) 07-15 22:09:45.402: E/AndroidRuntime(494): at android.os.Looper.loop(Looper.java:123) 07-15 22:09:45.402: E/AndroidRuntime(494): at android.app.ActivityThread.main(ActivityThread.java:4627) 07-15 22:09:45.402: E/AndroidRuntime(494): at java.lang.reflect.Method.invokeNative(Native Method) 07-15 22:09:45.402: E/AndroidRuntime(494): at java.lang.reflect.Method.invoke(Method.java:521) 07-15 22:09:45.402: E/AndroidRuntime(494): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 07-15 22:09:45.402: E/AndroidRuntime(494): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 07-15 22:09:45.402: E/AndroidRuntime(494): at dalvik.system.NativeStart.main(Native Method) 停止滚动时没有问题。

logcat的:

public class SearchAirportFragment extends DialogFragment {
    private Activity mContext;
    private SimpleCursorAdapter adapter;
    private Cursor cursor = null;
    private LoadCursor taskLoad;

    public static DialogFragment newInstance(int jenisPenerbangan) {
        DialogFragment f = new SearchAirportFragment();
        f.setRetainInstance(true);
        return f;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        mContext = activity;
    }

    @Override
    public void onDetach() {
        mContext = null;
        super.onDetach();
    }

    @Override
    public void onDestroy() {
        if (taskLoad != null)
            taskLoad.cancel(false);

        if (cursor != null) {
            cursor.close();
        }
        super.onDestroy();
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_search_airport, container, false);
        ListView listView = (ListView) view.findViewById(R.id.listView1);
        adapter = new SimpleCursorAdapter(mContext, R.layout.list_item_text, cursor, new String[] { "name" }, new int[] { R.id.text1 }, 0);
        listView.setAdapter(adapter);
        if (cursor == null && taskLoad == null) {
            taskLoad = new LoadCursor(this, 1, "test");
            taskLoad.execute();
        }
        return view;
    }

    @Override
    public void onDestroyView() {
        adapter = null;
        Dialog d = getDialog();
        if (d != null && getRetainInstance())
            d.setDismissMessage(null);
        super.onDestroyView();
    }

    public void updateCursor(Cursor result) {
        cursor = result;
        if (adapter != null) {
            adapter.changeCursor(cursor);
        }
    }


    private static class LoadCursor extends AsyncTask<Void, Void, Cursor> {
        private String keyword;
        private WeakReference<SearchAirportFragment> fragmentReference;

        public LoadCursor(SearchAirportFragment fragment, int myflag,
            String search) {
            this.keyword = search;
            this.fragmentReference = new WeakReference<SearchAirportFragment>(fragment);
        }

        @Override
        protected Cursor doInBackground(Void... params) {
            DatabaseHelper dbHelper = DatabaseHelper.getInstance(MyApplication.getContext());
            SQLiteDatabase db = dbHelper.getReadableDatabase();
            Cursor c = /* my query */;
            return c;
        }

        @Override
        protected void onCancelled(Cursor result) {
            if (result != null) result.close();
        }

        @Override
        protected void onPostExecute(Cursor result) {
            SearchAirportFragment f = fragmentReference.get();
            if (f != null && result != null) {
                f.updateCursor(result);
            }
        }
    }
}

DialogFragment:

ListView

更新

也许不知怎的getView()在被销毁之后仍然会被滚动(因此适配器的@Override public void onDestroyView() { adapter.swapCursor(null); adapter = null; Dialog d = getDialog(); if (d != null && getRetainInstance()) d.setDismissMessage(null); super.onDestroyView(); } 被调用)。

这解决了它:

{{1}}

0 个答案:

没有答案