使用 Retrofit2 插入 + 4500 个项目,每个项目有 7 列到 SQlite 数据库中

Inserting + 4500 items with 7 columns each into SQlite Database with Retrofit2

我正在为手持扫描设备开发 Android 应用程序,并希望通过 Retrofit2 从 MySQL 数据库下载大约 4.500 个项目到设备上的 SQlite 数据库中;因此,当我尝试一次下载所有项目时,它会减慢 UI 并冻结应用程序长达 5 分钟;我在谷歌上搜索了很多关于如何解决这个问题的方法,但现在还没有找到合适的解决方案;因此,我尝试通过在 For-each 循环中迭代并在后台威胁中使用 .stream() 和 .limit() ,像这样:

 public static void writeItemsToDatabase(Context mContext, String basic) {

        //creating the itemApi interface
        ItemApi itemApi = retrofit.create(ItemApi.class);

        //making the call object
        Call<List<Item>> call = itemApi.checkItems(basic);

        call.enqueue(new Callback<List<Item>>() {
            @Override
            public void onResponse(@NonNull Call<List<Item>> call,
                                   @NonNull Response<List<Item>> response) {
                if (response.isSuccess()) {
                    List<Item> itemList;
                    itemList =  response.body();
                    int dataSize = response.body().size();
                    Log.d(TAGGG, String.valueOf(dataSize));
                    itemList.forEach(List -> Log.d(TAGGG, String.valueOf(List.getEan())));
                    itemList.forEach(List -> Log.d(TAGGG, String.valueOf(List.getNo())));
                    class DownloadTask extends AsyncTask<String, Integer, String> {

                        // Runs in UI before background thread is called
                        @Override
                        protected void onPreExecute() {
                            super.onPreExecute();
                            // Do something like display a progress bar
                        }

                        // This is run in a background thread
                        @Override
                        protected String doInBackground(String... params) {
                            // Do something that takes a long time, for example:
                            for (int i = 0; i <= 3 ; i++) {
                                try (DatabaseHandler itemsManager = new DatabaseHandler((XXXXApp)
                                        mContext.getApplicationContext())) {
                                    itemList.stream().limit(1500).forEach(item -> {
                                        itemsManager.addItem(item);
                                        itemsManager.close();
                                    });
                                }
                                // Call this to update your progress
                                publishProgress(i);
                            }
                            return "this string is passed to onPostExecute";
                        }

                        // This is called from background thread but runs in UI
                        @Override
                        protected void onProgressUpdate(Integer... values) {
                            super.onProgressUpdate(values);
                            // Do things like update the progress bar
                        }
                        // This runs in UI when background thread finishes
                        @Override
                        protected void onPostExecute(String result) {
                            super.onPostExecute(result);
                            // Do things like hide the progress bar or change a TextView
                        }
                    }
                    new DownloadTask().execute();
                }
            }

            @Override
            public void onFailure(Call<List<Item>> call, Throwable t) {}
        });
        return;
    }

但是,结果并不令人满意,因为数据库没有正确下载;我将 i 的值更改为 9 并将 .limit() 的值更改为 500(以实现相同的结果,即下载 +4.500 项),结果相同。

问题肯定出在这段代码中:

for (int i = 0; i <= 3 ; i++) {
     try (DatabaseHandler itemsManager = new DatabaseHandler((XXXApp)
          mContext.getApplicationContext())) 
   {
         itemList.stream().limit(1500).forEach(item -> {
         itemsManager.addItem(item);
         itemsManager.close();
         });
         }
   // Call this to update your progress
publishProgress(i);
                           

}

这是我在大量谷歌搜索后找到的最接近我想要实现的方法;问题当然是每次关闭数据库并重新打开它的 For-Loop;我也不确定 SQlite 数据库的数据量是否太大;因此,非常感谢任何有关如何正确解决此问题的帮助或提示,谢谢!

  1. Create once instance of DatabaseHandler(what is it? you can use room with more comfortable API) and reuse it.
  2. Insert many(100-500) items in one transaction.

或者您可以在服务器端创建 sqlite 数据库文件,然后下载它并在 android 应用程序中作为数据库打开。