【问题标题】:Android - Create a very large ListView based on a SQL CursorAndroid - 基于 SQL 游标创建一个非常大的 ListView
【发布时间】:2011-08-25 14:43:25
【问题描述】:

我有一个返回数千行的 SQLite 查询,我想使用 ListView 对其进行可视化。

为了让我的 UI 线程保持响应,我在后台线程上创建了 ListAdapter

但是,花费最多时间(并且可能导致 ANR)的语句是 ListActivity.setListAdapter,我必须在 UI 线程上执行它...有什么建议吗?

公共类 CursorTestActivity 扩展 ListActivity { 私有静态最终字符串 LOGTAG = "DBTEST"; 私有数据库管理器 mDbManager; 私人光标 mCursor; 私有处理线程 mIOWorkerThread; 私有处理程序 mIOHandler; 私有处理程序 mUIHandler; @覆盖 公共无效 onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mDbManager = new DatabaseManager(this); mUIHandler = 新的处理程序(); createIOWorkerThread(); log("创建光标"); mCursor = mDbManager.getCursor(); // 执行 db.query(...) 开始管理光标(mCursor); mIOHandler.post(new Runnable() { @覆盖 公共无效运行(){ setMyListAdapter(); } }); log("onCreate 完成"); } 私人无效 setMyListAdapter() { log("构造适配器"); // CustomCursorAdapter 实现 bindView 和 newView 最终的 CustomCursorAdapter listAdapter = new CustomCursorAdapter(this, mCursor,假); log("完成构建适配器"); mUIHandler.post(new Runnable() { @覆盖 公共无效运行(){ log("设置列表适配器"); 设置列表适配器(列表适配器); // 返回的行越多越慢 log("设置内容视图"); 设置内容视图(R.layout.main); log("完成设置内容视图"); } }); } 私人无效createIOWorkerThread(){ mIOWorkerThread = new HandlerThread("io_thread"); mIOWorkerThread.start(); Looper looper = mIOWorkerThread.getLooper(); mIOHandler = new Handler(looper); } 私人无效destroyIOWorkerThread(){ 如果(mIOWorkerThread == null) 返回; Looper looper = mIOWorkerThread.getLooper(); if (looper != null) { looper.quit(); } } @覆盖 公共无效 onDestroy() { super.onDestroy(); 如果(mDbManager != null) mDbManager.close(); destroyIOWorkerThread(); } 私有静态无效日志(字符串 s){ Log.d(LOGTAG, s); } }

【问题讨论】:

    标签: android sql listview android-recyclerview cursor


    【解决方案1】:

    游标是延迟加载的,因此在第一次数据访问时会加载游标 - getCount 就是这样的访问。 setAdapter 方法在游标上调用 getCount - 存在性能问题。

    • 您可以在适配器中设置空光标并在加载光标时显示空列表。然后使用适配器中的 changeCursor 方法将光标更改为新的。
    • 您可以首先在第一个查询中获取例如 100 行,然后在后台加载更多行并将光标更改为新行。
    • 或者您可以创建自己的 Cursor 实现,该实现具有自己的 getCount 实现并根据请求获取所需的行。

    【讨论】:

      【解决方案2】:
      1. 考虑使用 PagedListAdapter。它与@pawelziemba 提出的类似,但由 Android 框架 https://developer.android.com/reference/android/arch/paging/PagedListAdapter 提供——如果您可以使用 Room 框架,您可以免费获得它
      2. 在 ViewHolder 中异步加载数据 - 如果需要重新绑定 viewHolder 并缓存加载的数据,请记住取消工作

      【讨论】:

        猜你喜欢
        • 2018-05-18
        • 2015-03-04
        • 2012-10-05
        • 1970-01-01
        • 2014-04-18
        • 1970-01-01
        • 2023-02-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多