如何处理来自 CSV 文件的数据并将该数据放入房间数据库并在 recylerview 中显示?

How to process data from CSV File and put that data in the room database and show it in recylerview?

检查回购 https://github.com/vivekpanchal/BabyApp

我正在读取数据并像这样更新适配器

CSV 文件位于 Raw 文件夹中的 repo 中

在处理 CSV 数据方面需要帮助

private void readData() {
    InputStream is = getResources().openRawResource(R.raw.babynames);
    BufferedReader reader = new BufferedReader(
            new InputStreamReader(is, Charset.forName("UTF-8"))
    );
    String line = "";

    try {
        reader.readLine();
        String mGender,mMeaning,mName,mOrigin;
        while ((line = reader.readLine()) != null) {
            Log.d("MyActivity", "Line: " + line);

            String[] tokens = line.split(",");

            mGender=tokens[1];
            mMeaning=tokens[2];
            mName=tokens[3];
            mOrigin=tokens[4];


            BabyName babyName=new BabyName(mGender,mMeaning,mName,mOrigin);
            babyName.setGender(mGender);
            babyName.setName(mName);
            babyName.setOrigin(mOrigin);
            babyName.setMeaning(mMeaning);
            database.babyDao().insert(babyName);
            babyNames.add(babyName);
            Log.d(TAG, "Just created: " + mGender+mMeaning+mName+mOrigin);

        }
    } catch (IOException e) {
        Log.wtf("MyActivity", "Error reading data file on line" + line, e);
        e.printStackTrace();
    }
}

我查看了你的 GitHub 项目 link,你的 CSV 文件有超过 22K 个条目。 另一件事是你 没有从房间读取数据 ,你刚刚插入了那些对象并用 ArrayList 更新了适配器。

首先你应该在主线程上执行这个CPU密集操作,这是长时间阻塞UI。 [刚刚在我的设备上测试代码]

使用工作线程或任何其他线程机制,如 RxJava 来执行此 CPU 密集型 操作。然后 return 结果到 主线程 并更新你的 UI.

更进一步,考虑到 22K 个条目,您应该考虑使用 Android 架构库

提供的 分页

在另一个线程上执行 private void readData() 操作,创建您的对象列表并同时插入到数据库中。使用如下所示的另一种 dao 方法

@Insert
void insertAll(List<BabyName> babyNames);

使用 database.babyDao().getAllData(); 方法在 Activity 中观察 List<BabyName> 并在该观察者中将 BabyNames 设置为适配器作为 adapter.setBabyNames(names) 并调用 adapter.notifyDatasetChanged()

这是您观察 LiveData 的方式 - 示例 ProductFragment

// Observe product data
model.getObservableProduct().observe(this, new Observer<ProductEntity>() {
    @Override
    public void onChanged(@Nullable ProductEntity productEntity) {
        model.setProduct(productEntity);
       // Update adapter data and notify dataset changed here
    }
});

如果您想遵循 Android 架构指南 考虑到您正在使用 Room 数据库,请使用 MVVM 架构。打开应用程序后,您将开始 CSV 处理任务,并且 UI 将使用 LiveData 观察数据库更改。因此,当您的 csv 处理完成并更新数据库时,您可以在 UI

中查看所有这些

参考此以获得分页支持 - Android Pagination

编辑 1

我在 GitHub 上创建了 Pull Request,它解决了这个问题。 现在应用 运行 符合预期。

它修复了以下问题

  • CSV 处理 在后台
  • BabyDao 需要 LiveData 方法
  • MainActivity with Observing Baby List
  • MainActivity 如果尚未插入则在后台处理 CSV
  • RecyclerView 正常工作 - LayoutManager 错误已修复