似乎Java機器在某些類型的循環上失敗,這些循環似乎對其系統檢查是無限的,但實際上是由循環類以外的代碼終止的。這種情況不常發生,但最近我在最近的TickleService中發現了這種情況,在這種情況下代碼的有限循環無故障運行,但需要任何外部終止的循環失敗。例如:Java機器拒絕某些形式的循環代碼
class TickleService extends Service{
...
void execute(){
while(true){
Log.e("Test","Tickle");
wait(1000);
}
}
...
}
上述情況導致系統ANR立即崩潰(CPU使用率> 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
}
...
}
這招無一例外產生執行且可靠地發癢相隔一秒。 運行了許多測試,都證實如果連續循環根據類之外的觸發器終止,則連續循環失敗,但如果內部終止,則會正確運行。最終,儘管我強烈懷疑Dalvik java機器中有目的的設計缺陷或意外錯誤導致了這個問題,但證據只是間接的。此外,我在Android中編寫的所有服務似乎都沒有出現這個問題。有人知道爲什麼嗎?我很想更好地理解這個問題。
我認爲你的修復最終會導致堆棧溢出 - 不知道「startService」是如何工作的(android沒有經驗)。 –