何时关闭SimpleCursorAdapter中使用的Cursor?

13

我正在使用SimpleCursorAdapter在ListView中显示结果,但由于在搜索(使用SearchView小部件)期间必须多次查询数据库,因此我担心光标可能会保持打开状态。

以下是我如何查询数据库并在ListView中显示结果的方式:

class SearchCustomers extends AsyncTask<String,Void,Cursor>{

        @Override
        protected Cursor doInBackground(String... params) {         
            //get the query
            String query=params[0].toLowerCase(Locale.getDefault());
            Cursor cursor=mDB.searchCustomersByName((query != null ? query : "@@@@"));
            return cursor;

        }

        @Override
        protected void onPostExecute(Cursor result) {           

            if (result != null) {

                String[] from = new String[] { QuickOrderDB.ID,
                        QuickOrderDB.NAME,
                        QuickOrderDB.ADDRESS,
                        QuickOrderDB.PHONE_NUMBER };

                int[] to = new int[] { R.id.customerIDTextView,
                        R.id.customerNameTextView,R.id.customerAddressTextView ,
                        R.id.customerPhoneTextView };

                SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(SearchCustomersActivity.this,
                        R.layout.results_customer_item, result, from, to);
                mResultsListView.setAdapter(cursorAdapter);                 

            }
        }           

    }   

我尝试了许多方法来关闭游标,但即使在 mResultsListView.setAdapter(cursorAdapter); 之后关闭它,结果始终都是:一个空的 ListView

我已经看到了几个问题,其中提到游标将自动关闭,但我想确保这是正确的。

是否有任何官方文档说明?SimpleCursorAdapter 是否真的会自动关闭游标?

谢谢!


唯一有效的方法是不要尝试关闭游标。但由于每次用户键入字母时都会调用mDB.searchCustomersByName,这让我担心可能会导致内存泄漏。 - Axel
如果在调用setAdapter后关闭它,那么适配器将无法获取任何数据,因为游标已经关闭。当您不再需要它时,请关闭它。提示:只要您正在显示来自游标的数据,您就需要保持游标处于打开状态。 - njzk2
通常情况下,如果在适配器中调用swapCursor函数,旧的光标会被关闭。 - njzk2
那么,我如何知道何时不再需要游标?我猜这将是当我离开 Activity 时,但我想我必须保留对游标的引用。 - Axel
simpleCursor适配器应该为您执行关闭操作。您可以通过研究加载器来获取更多信息。http://developer.android.com/reference/android/app/LoaderManager.LoaderCallbacks.html#onLoadFinished%28android.content.Loader%3CD%3E,%20D%29 - danny117
显示剩余8条评论
4个回答

6
  1. 在使用完光标后,需要关闭它。在 setAdapter() 调用之后关闭会阻止适配器访问数据。因此,更好的关闭光标的位置应该是在当前活动的生命周期阶段,例如 onPause() 或 onStop()。 (不应使用 onDestroy(),因为 Android 运行时不能保证调用它。我认为在最新版本中 onStop() 是有保证的)
  2. 我认为 SimpleCursorAdapter 不能自动关闭光标。官方文档提到 changeCursor() 会自动关闭旧的光标,因此另一个选项是在搜索后更改光标。 http://developer.android.com/reference/android/widget/CursorAdapter.html#changeCursor(android.database.Cursor)

2

最好使用CursorLoader而不是AsyncTask来获取游标。通过LoaderManager,Loaders与Activity/Fragment生命周期同步,当需要时系统会自动为您关闭由CursorLoader提供的游标。


0
你应该在你的Fragment或Activity的onPause()回调中关闭游标。在Activity暂停后,旧版的Android系统可能会删除应用程序以释放内存。
这意味着你需要在相应的onResume()回调中重新建立游标。

-3

不要为游标创建变量,只需将数据库查询直接添加到 构造函数 中作为参数 cdb.query() 或保存所需查询的方法。 这似乎可行。

SimpleCursorAdapter (Context context, 
                int layout, 
                Cursor c, 
                String[] from, 
                int[] to, 
                int flags)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接