过去三天我一直试图了解并解决这个问题。 我有多个ListActivities,每个ListActivities查询同一个数据库。在每个活动中,我分别关闭并重新打开onPause()和onResume()中的DB连接。我用光标填充列表适配器,我也关闭并重新打开:
@Override
public void onPause(){
super.onPause();
if(currentCursor != null){
currentCursor.close();
currentCursor = null;
}
if(mDbHelper != null){
mDbHelper.close();
mDbHelper = null;
}
}
@Override
public void onResume(){
super.onResume();
if(mDbHelper == null){
mDbHelper = new DbHelper(this);
mDbHelper.open();
}
if(currentCursor == null){
new LoadNewListTask().execute();
}
}
private class LoadNewListTask extends AsyncTask<String, Void, String> {
ProgressDialog dialog;
@Override
protected void onPreExecute() {
dialog = new ProgressDialog(context);
dialog.setMessage("Loading...");
dialog.show();
}
@Override
protected String doInBackground(String... arg0) {
try{
currentCursor = mDbHelper.fetchNewRows();
}catch(Exception e){}
return null;
}
@Override
protected void onPostExecute(String arg){
if(dialog != null && dialog.isShowing()){
dialog.dismiss();
}
if(currentCursor != null && currentCursor.getCount()>0){
String[] from = new String[]{DbHelper.KEY_ID, sortingColumn};
int[] to = new int[]{R.id.ai_about_author_btn, R.id.ai_author_name};
MyAlphabetizedAdapter notes = new MyAlphabetizedAdapter(this, R.layout.author_index_item, currentCursor, from, to, sortingColumn);
setListAdapter(notes);
}
}
}
乍一看它运作良好但是当我在各个活动之间快速移动时,我有时会讨厌Cursor Exceptions,这样说:
05-01 14:45:05.849: ERROR/AndroidRuntime(1145):
java.lang.IllegalStateException: attempt to acquire a reference on a
close SQLiteClosable
05-01 14:45:05.849: ERROR/AndroidRuntime(1145): at
android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:31)
05-01 14:45:05.849: ERROR/AndroidRuntime(1145): at
android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:56)
05-01 14:45:05.849: ERROR/AndroidRuntime(1145): at
android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:49)
05-01 14:45:05.849: ERROR/AndroidRuntime(1145): at
android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:49)
05-01 14:45:05.849: ERROR/AndroidRuntime(1145): at
android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1118)
05-01 14:45:05.849: ERROR/AndroidRuntime(1145): at
android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1092)
05-01 14:45:05.849: ERROR/AndroidRuntime(1145): at
apt.tutorial.Restaurant.getAll(Restaurant.java:14)
和另一个说这个(这在2.1设备上发生了很多):
09-03 11:30:19.713: INFO/dalvikvm(2541): Uncaught exception thrown by finalizer (will be discarded):
09-03 11:30:19.713: INFO/dalvikvm(2541): Ljava/lang/IllegalStateException;: Finalizing cursor android.database.sqlite.SQLiteCursor@45b99828 on null that has not been deactivated or closed
09-03 11:30:19.713: INFO/dalvikvm(2541): at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596)
09-03 11:30:19.713: INFO/dalvikvm(2541): at dalvik.system.NativeStart.run(Native Method)
我的ListActivities更多的是实现AlphabetIndexer,我必须传递光标。在我离开活动并使用后退按钮返回后发生了非常奇怪的事情。列表已填充(正如预期的那样)但是当我尝试使用快速滚动时,我在游标上得到一个空异常,即使我重新创建它并重新填充列表onResume()。
对我而言,操作系统似乎无法正确处理多个游标,或者我可能会错过这里的某些内容?
感谢您的帮助。
答案 0 :(得分:2)
由于您启动了异步任务并且您将活动保持为快速,因此意味着当任务返回时您将离开此活动,因此已调用onPause()
并且未关闭游标。您可以尝试取消onPause()
中的异步任务。
答案 1 :(得分:2)
一般情况下,我遇到过试图保持多个游标存活的活动的问题。特别是在尝试使用托管游标时,我现在尽量避免使用托管游标(加上它们已被弃用)。现在,我尝试做的是打开光标,用我需要的数据填充对象数组,关闭光标,然后使用ArrayAdapter填充ListView。如果您需要保持光标处于活动状态,并且您只需要在堆栈上的其他活动正在更改数据时使用游标管理器,或者更好的是使用较新的CursorLoader。执行此操作时,请不要关闭光标,因为您的活动将为您管理光标的生命周期。