【问题标题】:When to close Cursor used in SimpleCursorAdapter何时关闭 SimpleCursorAdapter 中使用的光标
【发布时间】:2014-11-25 13:41:04
【问题描述】:

我正在使用 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 真的会自动关闭光标吗?

提前致谢。

【问题讨论】:

  • 通常您会在使用后关闭它,然后在您再次需要时再抓取一个。
  • 但即使我在这部分 mResultsListView.setAdapter(cursorAdapter) 之后关闭光标,ListView 也不会显示任何内容
  • 通常你会在适配器上调用notifyDataSetChanged,以确保在稍后的给定时间点构建它们的信息在屏幕上更新。但是你的结构中可能还缺少其他东西。
  • 唯一有效的是不要尝试关闭光标。但是由于用户输入的每个字母都会调用mDB.searchCustomersByName,所以我担心我可能会导致内存泄漏
  • 如果在调用setAdapter后关闭它,那么适配器将没有任何数据可取,因为光标将被关闭。不再需要时关闭它。提示:只要是从光标显示数据,就需要打开光标。

标签: android simplecursoradapter searchview android-cursor


【解决方案1】:

最好使用 CursorLoader 而不是 AsyncTask 来获取 Cursor。 Loader通过LoaderManager同步到Activity/Fragment生命周期,系统会在需要时自动为你关闭CursorLoader提供的Cursor。

【讨论】:

    【解决方案2】:

    不要为游标创建变量,只需将 db 查询直接添加到 constructor 作为参数 cdb.query() 或保存所需查询的方法) ,这似乎有效。

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

    【讨论】:

      【解决方案3】:

      您应该在片段或活动的onPause() 回调中关闭光标。 Activity 暂停后,旧版 Android 系统可能会删除该应用以释放内存。

      这意味着你需要在对应的onResume()回调中重新建立光标。

      【讨论】:

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

        【讨论】:

          猜你喜欢
          • 2011-12-14
          • 1970-01-01
          • 1970-01-01
          • 2016-10-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-05
          • 1970-01-01
          相关资源
          最近更新 更多