我在保留的Cursor
中使用DialogFragment
。创建Cursor
视图后AsyncTask
加载DialogFragment
,DialogFragment
被销毁后关闭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}}