在获取数据并将其存储到 sqlite db 时,我的应用程序的 UI 冻结

While fetching data and storing it into sqlite db the UI of my app freezes

你好我的应用程序在从网络获取数据并将其存储在数据库中然后在 recyclerview 中显示时冻结 ui 几秒钟。为了从网络中获取数据,我正在使用改造并存储它并从 db Room 库中获取数据。两者都借助 MVVM 模式。有没有办法解除 UI 冻结? 这是我的代码:

在 Mainactivity 中点击下载 btn

downloadBtn.setOnClickListener(v -> 
  eventsViewModel.insertEvents(this));

视图模型class:

public void insertEvents(Context context){

        final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);

        String token = preferences.getString("token", "");

        final Map<String,String> queryData = new HashMap<>();
        queryData.put("token", token);
        Call<EventsResponse> call = RetrofitClient.getmInstance().getApi().getEvents(queryData);
        call.enqueue(new Callback<EventsResponse>() {
            @Override
            public void onResponse(Call<EventsResponse> call, Response<EventsResponse> response) {

                if (response.code() == 401){


                    String email = preferences.getString("email", "");
                    String password = preferences.getString("password", "");

                    Call<LoginResponse> call1 = RetrofitClient.getmInstance().getApi().loginuser(email, password);
                    call1.enqueue(new Callback<LoginResponse>() {
                        @Override
                        public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
                            if (response.code() == 200){

                                SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context); // 0 - for private mode
                                SharedPreferences.Editor editor = pref.edit();
                                editor.putString("token", response.body().getToken());
                                editor.apply();

                                insertEvents(context);

                            }
                            else {

                            }
                        }

                        @Override
                        public void onFailure(Call<LoginResponse> call, Throwable t) {

                        }
                    });
                }

                if (response.code() == 200){
                    eventList = response.body().getData();

                    EventsTable eventsTable = new EventsTable();

                    TicketDatesTable ticketDatesTable = new TicketDatesTable();

                    for (int i = 0; i < eventList.size(); i++) {

                        eventsTable.setEvent_id(eventList.get(i).getId());
                        eventsTable.setTitle_tk(eventList.get(i).getTitle_tk());
                        eventsTable.setTitle_ru(eventList.get(i).getTitle_ru());
                        eventsTable.setImageURL("https://bilettm.com/" + eventList.get(i).getImage_url());
                        eventsTable.setStart_date(eventList.get(i).getStart_date());
                        eventsTable.setEnd_date(eventList.get(i).getEnd_date());
                        eventsTable.setSales_volume(eventList.get(i).getEnd_date());
                        eventsTable.setOrganiser_fees_volume(eventList.get(i).getOrganiser_fees_volume());
                        eventsTable.setViews(eventList.get(i).getViews());
                        eventsTable.setSales_volume(eventList.get(i).getSales_volume());
                        eventsTable.setIs_live(eventList.get(i).getIs_live());

                        if (!eventList.get(i).getTicket_dates().isEmpty()) {

                            showTimeList = eventList.get(i).getTicket_dates();
                            int b = 0;
                            while (b < showTimeList.size()) {
                                ticketDatesTable.setEvent_id(showTimeList.get(b).getEvent_id());

                                ticketDatesTable.setTicket_date(showTimeList.get(b).getTicket_date());

                                insertTicketDates(ticketDatesTable);

                                try {

                                    Thread.sleep(150);

                                } catch (InterruptedException ex) {

                                    Thread.currentThread().interrupt();

                                }


                                b++;
                            }

                        }
                        insert(eventsTable);
                        try {
                            Thread.sleep(150);
                        } catch (InterruptedException ex) {
                            Thread.currentThread().interrupt();
                        }

                    }
                }
            }
            @Override
            public void onFailure(Call<EventsResponse> call, Throwable t) {

            }
        });

    }

public void insert(EventsTable data){
        repository.insertEvents(data);
    }

    public void insertTicketDates(TicketDatesTable ticketDatesTable){
        repository.insertTicketDates(ticketDatesTable);

这是我的存储库:

public void insertEvents(EventsTable data){
    new EventInsertion(eventsDAO).execute(data);
}
private static class EventInsertion extends AsyncTask<EventsTable, Void, Void> {

    private EventsDAO eventsDAO;

    private EventInsertion(EventsDAO eventsDAO) {
        this.eventsDAO = eventsDAO;
    }


    @Override
    protected Void doInBackground(EventsTable... eventsTables) {
        eventsDAO.insertEvents(eventsTables[0]);

        return null;
    }
}

public void insertTicketDates(TicketDatesTable data){
    new TicketDatesInsertion(eventsDAO).execute(data);
}
private static class TicketDatesInsertion extends AsyncTask<TicketDatesTable, Void, Void> {

    private EventsDAO eventsDAO;

    private TicketDatesInsertion(EventsDAO eventsDAO) {
        this.eventsDAO = eventsDAO;
    }


    @Override
    protected Void doInBackground(TicketDatesTable... ticketDatesTables) {
        eventsDAO.insertTicketDates(ticketDatesTables[0]);
        return null;
    }
}

这是我的 DAO:

@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertEvents(EventsTable data);

@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertTicketDates(TicketDatesTable datesTable);

我认为它在将其存储到 sqlite 数据库时会冻结

为什么要使用这个 Thread.sleep(150);Call 已经是改造中的后台任务

更好的解决方案是将所有需要的对象收集到 ArrayList 中,然后将其传递到 AsyncTask 并从那里传递到 DAO 以进行批量插入。

并删除所有 Thread.sleep(150) 条声明,因为它们毫无用处。

我发现了我的问题。它在开始 for 循环之前正在初始化实体:

之前:

EventsTable eventsTable = new EventsTable();

for (int i = 0; i < eventList.size(); i++) {
       INSERT();

     }

之后:

  for (int i = 0; i < eventList.size(); i++) {
             EventsTable eventsTable = new EventsTable();
             INSERT();
     }