【问题标题】:loading recycler/listview items efficiently有效地加载回收站/列表视图项目
【发布时间】:2016-05-10 13:34:19
【问题描述】:

我有一个应用程序可以在我的手机上从 sql database 加载项目,我所做的是我从 onResume() 方法加载项目,但查看事物并不是最有效的方式,我总是可以看到这些项目当我查看whatsAppcontacts 等其他应用程序时正在加载,应用程序甚至看不到正在加载的项目。以我目前的加载方式,我的应用程序不仅速度慢,而且还进行了不必要的处理,有没有人知道我可以实现的更好更有效的方式?非常感谢您。

我的 Sql 数据库类概述:

public class Database  extends SQLiteOpenHelper {

//My list that holds my database items(which in my case is receipts)
private ArrayList<Receipt> allReceipts = new ArrayList<>();

  public ArrayList<Receipt> getAllReceipts() {
    try {
        allReceipts.clear();

        // Select All Query
        String selectQuery = "SELECT  * FROM " + Constants.RECEIPT_TABLE;

        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);

        // looping through all rows and adding to list
        if(cursor != null)
        if (cursor.moveToFirst()) {
            do {

                Receipt receipt  = new Receipt();
                receipt.setId(Integer.parseInt(cursor.getString(0)));
                receipt.setMerchantName(cursor.getString(1));
                receipt.setPrice(cursor.getString(2));
                // Adding contact to list
                allReceipts.add(receipt);
            } while (cursor.moveToNext());
        }


        if(cursor != null)
        cursor.close();
        db.close();
        return allReceipts;
    } catch (Exception e) {
        // TODO: handle exception
        Log.e("all_receipts", "" + e);
    }

    return allReceipts;
}

收到收据的我的片段

 private void initRecycler()
 {
    Action<List<ParentListItem>> action = new Action<List<ParentListItem>>() {

        @NonNull
        @Override
        public String id() {
            // Return a unique ID.
            return "load all receipts";
        }
        @Nullable
        @Override
        protected List<ParentListItem> run() throws InterruptedException {
             receiptArrayList = database.getAllReceipts();
            return getReceipts();
        }

        @Override
        protected void done(@Nullable final List<ParentListItem> receipts) {
            progress.stop();

            assert receipts != null;
            if(receipts.isEmpty()) {



            }else {

                childAdapterListeners();



                adapter = new ReceiptExpandableAdapter(getContext(), receipts, onItemClickListenerCheckBtn, onItemClickListenerDeleteBtn, mOntemClickListenerViewBtn);
                recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
               // recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));
                recyclerView.setAdapter(adapter);

            }
        }
    };
    action.execute();
  }



  @Override
public void onResume()
{
   initRecycler();
   super.onResume();

}

【问题讨论】:

  • 这真是一个宽泛的问题,有很多因素吗?可以发一下代码吗?
  • 请稍等
  • 尝试获取有限数量的数据记录(页)。仅当用户滚动到它们时才获取下一页。
  • 我该怎么做?

标签: android sqlite android-recyclerview


【解决方案1】:

您是否尝试过扩展 CursorLoader?这是使用数据库数据填充列表的最有效和正确的方法。

【讨论】:

  • 请您进一步解释一下
  • 这是从光标加载项目的最有效方式。也是谷歌推荐的。因为它管理配置更改的游标。你可以很容易地将方法 swapCursor 添加到你的 recyclerview 适配器中。
  • 该示例展示了如何将它与 SimpleCursorAdapter 一起使用。但是,使用任何自定义适配器来实现并不难。是那个基本适配器或回收器视图适配器。您只需要在适配器的构造函数中提供光标并在加载完成或重置时交换它。 CursorLoader 扩展了 AsyncLoader,后者又扩展了 AsyncTask。因此,数据的加载是在后台线程上完成的,当加载器完成或重置时,您可以覆盖对 ui 线程的回调。您在 onLoaderFinished 方法中初始化您的适配器。并将其设置为列表。