PostDelayed работает некорректно

Я использовал postDelayed для задержки динамической продолжительности. И я обнаружил, что это не работает правильно. Вот мой исходный код.

public Runnable service = new Runnable() {
        public void run() {     
            endTimeHere = System.currentTimeMillis();
            Log.d("Time",(endTimeHere-startTimeHere)/1000);
            switch (step)
            {
                case 0: 
                    delay = 0;
                    step = 1;
                    break;
                case 1:
                    delay = 600;        //delay 10 min = 600 sec
                    step = 2;
                    break;

                case 2:     
                    delay = 1200;   //delay 20 min = 1200 sec
                    step = 3;
                    break;
                case 3:     
                    delay = 1800;   //delay 30 min = 1800 secs
                    step = 0;
                    break;
                default:
                    break;
            }
            startTimeHere = System.currentTimeMillis();
            handler.postDelayed(service, delay*1000);   
        }
    };

И я запускаю и останавливаю обработчик в BroadcastLintener.

public Handler handler = new  Handler();    
private BroadcastReceiver screenReceiver = new BroadcastReceiver()
    {
        public void onReceive(Context context, Intent intent)
        {
            String action = intent.getAction();
            if(Intent.ACTION_SCREEN_ON.equals(action))
            {
                handler.removeCallbacks(service);
            }
            else if(Intent.ACTION_SCREEN_OFF.equals(action))
            {
                handler.post(service);
            }
        }
    }

Я уверен, что postDelayed добавляется в очередь, потому что возвращаемое значение истинно. Однако продолжительность времени, которую я записал, не соответствует установленному мной значению задержки. Например, я установил задержку = 600 секунд, а длительность записи = 958 секунд.

Кто-нибудь знает, почему это произошло?


person iscnorthwind    schedule 05.02.2014    source источник
comment
Вы пробовали этот код с частичной блокировкой?   -  person marcinj    schedule 06.02.2014
comment
Неа. Это связано?   -  person iscnorthwind    schedule 06.02.2014
comment
стоит попробовать, ваше устройство может спать после ACTION_SCREEN_OFF   -  person marcinj    schedule 06.02.2014
comment
Спасибо, после частичной блокировки вейклока все работает.   -  person iscnorthwind    schedule 06.02.2014


Ответы (1)


Хэндлеры не умеют стрелять именно тогда, когда должны. Другие потоки (например, поток пользовательского интерфейса) могут иметь приоритет. Кроме того, у Android есть накладные расходы на обработку Intent. Другими словами, обработчик может сработать на 650 мс из-за задержек в мониторинге потока со стороны ОС, но затем необходимо обработать намерение, создать экземпляр получателя, обработать намерение и т. д.

Возможно, вам лучше отправить намерение с данными о задержке, а затем настроить службу в очереди и часто опрашивать ее на основе ожидаемой задержки. например событие, запланированное на 500 мс в будущем, возможно, следует опрашивать каждые 50 мс, чтобы узнать, истекло ли время задержки. В то время как событие 10 000 мс в будущем может быть опрошено через 5 000 мс или 9 000 мс, а затем увеличивать частоту опроса по мере приближения времени.

person Jim    schedule 05.02.2014