2015-11-24 48 views
0

我正在使用Android Studio和模擬器​​android 4.1.2。 我的代碼android處理程序 - 確定,定時器 - 不幸停止。爲什麼不同?

Timer timer = new Timer(); 
    timer.schedule(new TimerTask() { 
     @Override 
     public void run() { 
      myRun(); 
     } 
    },10000,10000); 

結果「不幸的是,應用程序已經停止」,但是我發現代碼

Handler handler = new Handler(); 
    handler.postDelayed(new Runnable() { 
     public void run() { 
      myRun(); 
     } 
    }, 2000); 

運行正常,並顯示如我所料。 這兩者之間的內在區別是什麼?

P.S.

public void myRun() { 
    myView.removeAllViews(); 
    drawView = new DrawView(myContext, myView); 
    myView.addView(drawView); 
} 

我試圖永久更新自定義視圖,直到用戶取消它。只是週期

while (myRun) { 

結果模擬器變得反應遲鈍到連後退按鈕,運行更新的第二個線程

new Thread(new Runnable() { 
     @Override 
     public void run() { 
      while (myRun) { 

       myView.post(new Runnable() { 
        public void run() { 
         myView.removeAllViews(); 
         drawView = new DrawView(myContext, myView); 
         myView.addView(drawView); 
        } 
       }); 

      } 
     } 
    }).start(); 

結果相同(有趣的是我,如果我用的斷點上,而在第二運行調試線程,屏幕更新,因爲我預計很多次,但運行w/out調試不會更新屏幕)。

+0

請張貼您的錯誤日誌。 – starkshang

回答

0

Timer執行上僅用於服務通過這個特殊的定時任務創建一個單獨的線程任務。 Handler在其可能或可能不是UI線程的Looper線程上運行其任務。一般來說,如果你在一個單獨的線程上使用Handler,這兩個類之間沒有太大的區別。但在Android中使用Handler和HandlerThread更爲常見。

如果您需要與UI交互,你最好使用Handler

0

這是一個有趣的問題和答案在於android遵循的線程/ GUI策略。

我們知道,UI在主線程上運行。 Timer創建一個不同的線程,android不允許在另一個線程中更新UI。爲什麼?

假設,你已經開始在你的活動線程更新一個TextView和線程運行時,你移動到一些其他的應用程序。現在,主線程不再存在,當另一個線程嘗試更新TextView時,它無法找到該TextView。結果,我們看到了崩潰。

現在讓我來看看TimerTask和Handler之間的區別。

TimerTask創建一個新的線程,等待指定的時間,然後在同一個線程中執行run()方法。另一方面,Handler創建一個新的線程,等待指定的持續時間,然後返回主線程並在主線程(如果處理程序在主線程上)執行run()方法。因此,它工作正常。

但是你也可以用定時器來做。 請參見下面的代碼:

final Runnable setRunnable = new Runnable() { 
    public void run() { 
     myView.removeAllViews(); 
     drawView = new DrawView(myContext, myView); 
     myView.addView(drawView); 
    } 
}; 

TimerTask task = new TimerTask(){ 
    public void run() { 
     getActivity().runOnUiThread(setRunnable); 
    } 
}; 

Timer timer = new Timer(); 
timer.schedule(task, 1000); 

在這個線程要設置一個可運行的定時器的時間後對UI線程上運行。

+0

非常感謝你! –

相關問題