階段一:用Handler和Message實現計時效果及其中一些疑問,handlermessage
“階段一”是指我第一次系統地學習Android開發。這主要是對我的學習過程作個記錄。
本來是打算繼續做天氣預報的最佳化的,但因為某些原因,我要先把之前做的小應用最佳化一下。所以今天就插播一下用Handler和Message實現計時效果。
首先,簡要說明一下,這個應用有兩個顯示數位Text,一個是顯示秒,另一個是顯示毫秒,而每10毫秒發送一次Message,讓顯示毫秒的Text加1,每1000毫秒,也就一秒,就讓顯示秒的Text加1。此外,還有一個自己製作的圓形進度條,每過一秒會增加6度的弧。這個應用有開始、暫停、重設功能。就是這樣子:
一、sendMessage、handleMessage實現跑秒,removeMessages實現暫停
主要流程是這樣的:
說明:
(1)sendMessage都是延遲發送,也就是sendMessageDelayed。
(2)invalidate是重新整理視圖,用來重新整理上面提到的圓形進度條。
詳細來講,就是單擊開始按鈕,發送第一個Message,然後傳到handleMessage中處理,之後便在handleMessage中迴圈發送Message並處理。而當點擊暫停按鈕時,就會清除掉訊息佇列中的訊息,也就打破了迴圈。
接下來,詳細講講Message的處理流程這部分,如:
說明:
(1)當有message發送來時,並不會直接添加到MessageQueue中,它需要Looper和Handler對象一起作用,才會添加進去。另外,MessageQueue中的Message是由Looper派遣出去的。
(2)根據(1)知道,要處理message,必須要有Looper。所以在其它線程執行handleMessage時,必須要建立Looper。因為除了主線程預設有Looper之外,其它線程都是沒有的。而每一個Handler執行個體都會和一個線程和這個線程的MessageQueue關聯起來。
(3)當要在handleMessage裡面發送message時,是通過Message.obtain方法擷取message對象,這方法是從一個叫公用資訊池的地方擷取對象的,我的感覺是,這裡的對象就是接收到的message。
(4)在上一張圖中,暫停就是調用removeMessages方法。移除掉的就是在MessageQueue中的message。
我想講的主要就是上面的那些,以下是開始的那個流程圖的代碼,:
,只能是靜態:
二、一些疑問
(1)這裡的Handler是一個靜態類,老師提倡這麼寫。我之前是這樣寫的:
但其實,這麼寫Android Studio已經有提示了
我能理解到的就是,如果在主線程中Handler使用Looper或者MessageQueue時,就需要聲明Handler為靜態類,還有要用上WeakReference弱引用,這麼做是為了便於回收。具體是怎樣的,還需深入學習。
(2)用new傳入Context的方法建立CircularView(自訂View)的對象,能調用CircularView類的公有方法並修改了其中的成員變數,但就是不能成功調用invalidate重新整理方法。
構造方法是按老師教的修改,但老師並沒有示範這樣做。構造方法如:
通過打Log輸出(圖沒貼上來),可以知道的確成功調用了自訂View類CircularView中的方法。
但當我通過findViewById的方法來建立對象時,不僅能調用CircularView類的公有方法並修改了其中的成員變數,還能成功調用invalidate方法。
對此,我就輸出它們倆的對象,看一下,如:
這是通過findViewById的方法來建立的
這是通過new傳入Context方法建立的
發現它們建立的對象原來是不一樣的。我也只能研究到這一步了,所以要深入學習的還有很多啊!