Вызываемый и будущая задержка основного потока Android

Я хочу получить некоторые данные из службы по вызываемому и будущему. Это один из моих кодов:

@Override
public void getCIFilesType(Consumer<String> consumer) {
    try {
        consumer.accept(serviceExecutor.submit(() ->
                service.getCi(EsupFactory.getConfigString(SETTING_ROOT_CI) + "GetCI",
                        translator.makeCiJsonObject("PCiName", "CI_FilesType")).execute())
                .get().body().string());
    } catch (ExecutionException | InterruptedException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

У меня есть 10 таких методов, которые выполняются, как указано выше. Я использовал службу Executor для запуска callable:

ExecutorService serviceExecutor = Executors.newSingleThreadExecutor();

Я в своей деятельности У меня есть меню, а затем нажмите на один элемент в меню, фрагмент - это транзакция в действии. Все задачи потока немедленно стартовали в onViewCreated во фрагменте:

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    presenter.getCis();
}

Но когда я нажал на пункт меню UI, он затухает до тех пор, пока вся задача не будет завершена, а затем транзакция не будет завершена. У меня не первый раз такая проблема. Каждый раз, когда я использую вызываемый и исполнительный сервис, я не знаю, почему пользовательский интерфейс завивается!!!!

Это профайлер:

введите здесь описание изображения

У кого-то есть руководство для меня!!? Пожалуйста, не говорите мне использовать asyncTask :-)

Что такое строка чтения?? В потоке пользовательского интерфейса я просто выполняю транзакцию, а не выполняю длительную задачу !!!


person Cyrus the Great    schedule 19.02.2019    source источник


Ответы (1)


Это происходит потому, что вы вызываете get() для будущего, возвращаемого методом execute(). Согласно документам,

Если вы хотите сразу заблокировать ожидание задачи, вы можете использовать конструкции вида result = exec.submit(aCallable).get();

Таким образом, даже если вы используете фоновый поток, вызывая get, вы блокируете свой основной поток до тех пор, пока фоновый поток не завершит вашу задачу.

Чтобы избежать нежелательной почты пользовательского интерфейса, вы должны были использовать обратные вызовы.

person Stanislav Shamilov    schedule 19.02.2019
comment
Что означает used callbacks? Я использовал Consumer в качестве обратного вызова!! Я не понял, к чему ты used callbacks ?@StanislavShamilov - person Cyrus the Great; 19.02.2019
comment
Да, вы использовали его как обратный вызов, но проблема в том, что вы вызываете метод get. Как я упоминал ранее, это метод блокировки, поэтому вызывающий поток (в данном случае это основной поток Android) будет заблокирован до тех пор, пока фоновый поток не завершит свою задачу. Таким образом, вызов метода accept Потребителя будет отложен до тех пор, пока этот метод get не будет выполнен. - person Stanislav Shamilov; 19.02.2019
comment
Я думаю, что этот пост SO может вам помочь: stackoverflow.com/questions/826212/. Или вы можете попробовать использовать некоторые фреймворки для решения параллелизма, например, RxJava. - person Stanislav Shamilov; 19.02.2019