JohnDaniels
@JohnDaniels

Почему The application may be doing too much work on its main thread если «much work» выполняется в отдельном потоке?

В приложении есть функция обновления бд с сервера, в которой происходит парсинг json и запись в базу. Выполняется это дело 4-5сек, поэтому нужно сделать индикатор прогресса.
Остановился на решении с ProgressDialog.

Сначала сделал примерно так
public class AssetListActivity extends ActionBarActivity {
     //код неполный
     public boolean onOptionsItemSelected(MenuItem item) {
          try {
                String res = new ClientAsset(mDBConnector).execute(language).get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }

            this.recreate();
            return true;
            return super.onOptionsItemSelected(item);
     }

public class ClientAsset extends AsyncTask<String, Void, String> {

       @Override
        protected void onPreExecute() {
            Indicator.setMessage("прогресс");
            Indicator.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            Indicator.setProgress(0);
            Indicator.setMax(100);
            Indicator.show();
           //до обновления индикатора пока не дошел
        }

        @Override
        protected String doInBackground(String... params) {
             //тут долгая операция
        }
}
}


Запускаю - ошибок нет, но прогресс появляется после завершения doInBackground
в логе следующее:
I/Choreographer﹕ Skipped 413 frames! The application may be doing too much work on its main thread.
тут нашел что "значит, что ваше приложение блокирует основной поток на слишком длительное время."
Но почему AsyncTask блокирует основной поток?

первое что пришло в голову - вынес код индикатора в обработчик клика, то есть
@Override
    public boolean onOptionsItemSelected(MenuItem item) {
 
            Indicator.setMessage("прогресс");
            Indicator.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            Indicator.setProgress(0);
            Indicator.setMax(100);
            Indicator.show();

            try {
                String res = new ClientAsset(mDBConnector).execute(language).get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }

            this.recreate();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }


Но проблема осталась. Почему, ведь теперь индикатор и обновление бд в разных потоках? или я чего-то не понимаю?

P.S. в также AsyncTask не срабатывает onPostExecute, AndroidStudio говорит что такого метода вообще нет.
d4b4201273f9480ea7eba024a18c7c7a.png
  • Вопрос задан
  • 5583 просмотра
Решения вопроса 1
@FoxInSox
Зачем вы вызываете метод get своего AsyncTask'а? Он и блокирует ваш UI поток. Вы дожны вызывать execute и ждать результата в onPostExecute. В документации есть пример, не нужно изобретать велосипедов.
AndroidStudio все правильно говорит: нет метода onPostExecute(Void), в вашем случае есть onPostExecute(String). Читайте про дженерики.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы