Java-машина отвергает некоторые формы зацикливания кода - PullRequest
2 голосов
/ 11 октября 2011

Может показаться, что на Java-машине происходит сбой в определенных типах цикла, которые кажутся бесконечными для проверки системы, но на самом деле завершаются кодом вне класса цикла.Это случается не часто, но это было наиболее заметно в моем недавнем TickleService, где конечные циклы кода выполнялись без проблем, но циклы, которые требовали ЛЮБОГО внешнего завершения, не выполнялись.Например:

class TickleService extends Service{
...
    void execute(){
        while(true){
            Log.e("Test","Tickle");
            wait(1000);
        }
    }
...
}

Вышеуказанное вызвало немедленный сбой ANR системы (загрузка ЦП> 99% исключение).Однако следующая версия будет работать только один раз и прекратит дальнейшую работу без сбоев:

public class TickleService extends Service{
...
    public static boolean amNotAlive = false;
    void execute(){
        while(true){
          Log.e("Test","Tickle");
          if(amNotAlive)
            break;
          wait(1000);
        }
    }
...
}

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

public class TickleService extends Service{
...
    public static boolean amNotAlive = false;
    void execute(){
        for(int i = 0; i<5;i++){
            Log.e("Test","Tickle");
            wait(1000);
        }
    }
...
}

Этот цикл будет выполняться 5 раз каждые секунды, как и ожидалось.В конечном счете, исправление, которое я применил, состояло в следующем: я пытался обмануть JVM, думая, что зацикливание вообще не происходит:

public class TickleService extends Service{
 ...
 public static boolean amAlive = true;
 void execute(){
    Log.e("Test","Tickle");
    wait(1000);
    if(amAlive)
      restartService(); //pseudo code for doing startService on self
 }
 ...
}

Этот трюк, выполненный без исключения, надежно генерирует тикки с интервалом в одну секунду,Было выполнено много тестов, все подтвердили, что непрерывные циклы завершились неудачно, если они завершились в соответствии с триггерами вне класса, но работали правильно, если были завершены внутри.В конечном счете, хотя я и сильно подозреваю, что эта проблема была вызвана либо целенаправленной ошибкой проектирования, либо непреднамеренной ошибкой в ​​Java-машине Dalvik, но доказательства были лишь косвенными.Кроме того, проблема, кажется, не возникает для всех служб, которые я написал в Android.Кто-нибудь знает, почему это?Я хотел бы лучше понять эту проблему.

1 Ответ

3 голосов
/ 11 октября 2011

Виртуальная машина Dalvik работает правильно во всех случаях, которые вы показали. Запуск бесконечных циклов и, таким образом, блокирование основного потока пользовательского интерфейса - плохая практика, и вы получите только ошибки ANR. Я не видел ваш другой код, поэтому не могу ответить на него.

...