AsyncTask - Как использовать обработчик с postDelayed (Runnable, int) внутри AsyncTask? - PullRequest
0 голосов
/ 29 августа 2018

Я пытаюсь записать из BufferedInputStream, раньше я использовал оператор while, и он работал хорошо, но теперь я хочу отложить цикл записи каждого 250 millisecond. Итак, я подумал об использовании Handler с postDelayed.

Это был мой код, используя while:

while (count = input.read(data)) > 0){
//File writing...
}

Но когда я обратился к этому:

 new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                try {
                    //File writing...
                } catch (IOException e) {
                }
            }
        }, 250);

Я получил это RuntimeException :

Невозможно создать обработчик внутри потока, который не вызвал Looper.prepare ().

Я думаю, это говорит о том, что я не могу создать обработчик внутри потока (AsyncTask / Thread), но я надеюсь, что у кого-то есть обходной путь для этого. Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

Да, Handler отправляет сообщения на Thread, на котором вы его создаете - это означает, что вы создали свой обработчик в другом потоке, где циклический элемент не настроен по умолчанию (тогда как в основном потоке циклический элемент устанавливается по умолчанию - вот почему обработчики работают сразу при создании в главном потоке).

Вы можете использовать стандартную Java Timer для планирования действий на будущее, этот таймер использует свой собственный поток для выполнения ваших действий, например:

Timer timer = new Timer();
timer.schedule(new TimerTask() {
            @Override
            public void run() {
                // your action
            }
        }, your delay);

Другим решением будет использование RxJava, однако, если вы не знакомы с ним, потребуется некоторое время для изучения. Пример кода, который запускает ваше действие в другом потоке, возвращает результат в основном потоке и задерживается на 250 миллисекунд:

  (Kotlin here) Completable.fromAction(object : Action {
        override fun run() {
            // your action
        }
    }).subscribeOn(Schedulers.newThread())
            .subscribeOn(AndroidSchedulers.mainThread())
            .delay(250, TimeUnit.MILLISECONDS)
            .subscribe()

AsyncTask обычно устаревают, чтобы выполнять любые потоки

0 голосов
/ 29 августа 2018

Попробуйте вызвать Thread.sleep () вместо вызова postDelayed для обработчика, потому что внутри метода doInBackround вы уже находитесь в фоновом потоке и нет проблем с вызовом sleep в течение небольшого интервала времени

  try {
        Thread.sleep(250)   
        //File writing...
  }catch (IOException e) {

      }catch (InterruptedException e) {

      }

`

...