2012-10-22 73 views
3

我正在寫一個Android應用程序,需要顯示一些文本的千分之幾秒,然後再次空白它。我現在擁有的是顯示文本,然後使用Thread.sleep,然後將文本設置爲空。相反,發生的情況是,當我按下按鈕時,應用程序會掛起一段時間,文本永遠不會顯示,並且logcat會顯示「跳過了xxx幀!應用程序可能在其主線程上做了太多工作。」發生了什麼事情,還有更好的做事方式嗎?爲什麼我的android應用程序在調用Thread.sleep時跳過幀?

+0

所用的設備要測試它? – Lucifer

+0

@Lucifer - 一個Nexus 7. – SaintWacko

+0

好吧,以及不知道該設備,但一些設備不支持'Thread.sleep()' – Lucifer

回答

4

嘗試使用可運行。

private Handler mHandler = new Handler(); 

//code to make text appear... 

    mHandler.postDelayed(makeTextDisapear , 3000); // Replace 3000 with the number of milliseconds you want the text to display. 

    private Runnable makeTextDisapear = new Runnable() { 
      public void run() { 
       // code to make text dissapear 

       } 
      }; 
+0

當我嘗試這個,它說:「非法修改參數mHandler;只有最後被允許」 – SaintWacko

+0

更改私人最終 –

+0

是的,它工作時,我這樣做,只是檢查是否有某些原因,你用私人而不是最終。 – SaintWacko

2

,而其他的答案可以幫助您解決問題,您的問題也就是爲什麼會出現這種情況:

調用任一Thread.sleep()靜態方法卻將其方法是從調入暫停狀態的線程(大致)您指定的時間量(不能保證完全匹配指定的時間)。

在Android中,UI操作都可以在「主」 UI線程上執行,作爲UI框架的目的不是線程安全的。也就是說,當您設置TextView的文本時,您必須在主線程上調用textView.setText(...)setText將發佈消息的主要Looper重新佈局和無效的TextView(及家長)。在不久的將來,這些消息將被處理並且視圖層次結構將被更新。

setText不直接執行此項工作,因爲此工作負載很重,而直接執行此操作不會允許框架批量處理此類請求。

如果您然後調用Thread.sleep(...),則會將主UI線程置於暫停狀態,但是,此線程通常會執行TextView和父項的重新佈局和無效。

的Android希望能夠呈現一個新的框架(如果說有什麼改變)下16ms的保持60fps的相比更大。如果您的主線程正在進行大量的工作,或者在任何可能威脅16ms的時間內(通過休眠)暫停,那麼您看到的錯誤信息將發佈到logcat。

雖然在棒棒糖中,實際的渲染是在它自己的渲染線程上執行的,但它仍然需要主線程的及時更新。

至於如何解決這個問題,看到賈森的回答,或者發佈延遲的可運行使用

textView.setText("show me!");  
textView.postDelayed(new Runnable() { 
    public void run() { 
     textView.setText(""); 
    } 
}, 30); 

如果這經常發生的視圖本身(而不是直接處理程序實例),避免每次將Runnable作爲字段進行分配。

請注意,無論在哪種情況下,創建一個匿名內部類(Runnable)都有可能導致內存泄漏該活動,但這是一個不同的故事。

+0

啊,好吧!很高興知道,謝謝!我試圖睡覺的時間大大少於16毫秒,但這可能仍然是問題。 – SaintWacko

相關問題