Последовательность выполнения попытки/поймать Android

чего я хочу добиться, так это того, что при нажатии приложение показывает всплывающее сообщение «TEXT1» и продолжает показывать TEXT1 до завершения вызова другой функции 20 раз со случайным интервалом/задержкой. После вызова функции показывает всплывающее сообщение «TEXT2». Моя проблема: TEXT1 не отображается, пока приложение не завершит вызов функции. и TEXT1 поддерживает время, необходимое для выполнения 20-кратного вызова функции, затем появляется TEXT2. Мой код:

public void onClick(View v) {
    switch (v.getId()) {
        case R.id.example:
                Toast.makeText(getBaseContext(),"Please wait until finish",Toast.LENGTH_SHORT).show();
                int i = 0;
                while (i <= 19 ){

                    int delay = new Random().nextInt(5000);
                    try {
                            Thread.sleep(delay);
                        } catch(InterruptedException ex) {
                            Thread.currentThread().interrupt();
                        }
                    //some function here
                    i++;
                }
                Toast.makeText(getBaseContext(),"Finished",Toast.LENGTH_SHORT).show();
                break;
        }
    }
}

person tikael    schedule 18.09.2016    source источник


Ответы (1)


Никогда не блокируйте поток пользовательского интерфейса!

Все операции пользовательского интерфейса обрабатываются в потоке пользовательского интерфейса. Если вы заблокируете поток пользовательского интерфейса вызовом Thread.sleep, произойдет ANR (приложение не отвечает). Более того, Thread.sleep никогда не будет правильным способом создания таймеров, если только вы не пишете сердцебиение рабочего потока.

Вместо этого вы должны использовать Handler.postDelayed:

public void onClick(View v) {
    final Handler handler = new Handler();
    final Random random = new Random();

    Runnable runnable = new Runnable() {
        private int count = 0;

        @Override
        public void run() {
            count++;
            if(count > 20) { // 20 times passed
                Toast.makeText(getBaseContext(), "Finished", LENGTH_SHORT).show();
                return;
            }

            Toast.makeText(getBaseContext(), "Please wait until finish", LENGTH_SHORT).show();
            handler.postDelayed(this, random.nextInt(5000));
        }
    };
    runnable.run();
}

Изменить: ОП хотел использовать что-то вроде этого. https://gist.github.com/SOF3/07c3c110aa214fcdd752e95573b7076f

Смотрите также:

person SOFe    schedule 18.09.2016
comment
этот метод вызывает мою функцию с ФИКСИРОВАННЫМ интервалом, чего я не хочу. - person tikael; 18.09.2016
comment
Затем просто измените 1000 на ваше случайное число. Но разве вы не говорили, что хотите, чтобы всплывающее сообщение появлялось постоянно? - person SOFe; 18.09.2016
comment
да, я так и сделал. В общем, мой код должен выглядеть примерно так: final Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { } }, Myrandomnumber); ? - person tikael; 18.09.2016
comment
Отложите это с помощью random.nextInt(). Сделайте объект Random final. Создайте поле класса, в котором хранится, сколько раз вызывался этот runnable. Редактирование в минуту, чтобы показать вам, как. - person SOFe; 18.09.2016
comment
@tikael Отредактировано. - person SOFe; 18.09.2016
comment
Я тестировал, всплывающее сообщение не отображается... хотя пользовательский интерфейс продолжает обновляться. - person tikael; 18.09.2016
comment
Показывается с первого раза? Вы добавили последнюю строку runnable.run()? Неразумно, что он не показывает никаких тостов (если только у вас нет проблем на вашей стороне), потому что runnable должен по крайней мере показывать тост в любом случае, postDelayed или нет. - person SOFe; 18.09.2016
comment
это не так, и я добавил runnable.run() - person tikael; 18.09.2016
comment
@tikael Добавьте сообщение logcat в метод run внутри Runnable. Если ваш код запущен, это сообщение logcat должно отображаться. Если сообщение logcat отображается, но всплывающее уведомление не отображается, у вашего всплывающего уведомления возникла проблема. - person SOFe; 18.09.2016
comment
Я добавил Log.i(TAG,"yes"); прямо под пожалуйста, подождите... и я вижу TAG:yes в окне logcat--info... до сих пор нет всплывающего сообщения...так странно. - person tikael; 18.09.2016
comment
Попробуйте изменить контекст? Возможно, вы используете неправильный контекст. - person SOFe; 18.09.2016
comment
еще одна вещь, вся функция вызывает тост для каждого цикла, есть ли способ показать, пожалуйста, подождите .. постоянно? может быть, я должен настроить Toast.LENGTH? - person tikael; 18.09.2016
comment
Давайте продолжим это обсуждение в чате. - person SOFe; 18.09.2016