Handler在android程序開發中使用的非常頻繁、我們知道android是不允許在子線程中更新UI的,這就需要借助Handler來實現,那么你是否想過為什么一定要這個這樣子做呢?而且Handler的內部消息處理機制究竟是什么樣的呢,我們了解了之后還可以做點什么事?帶着這些疑問我系統的學習了一個講解Handler原理的課程,今天就在這里將自己的學習收獲總結下來。畢竟好記性不如爛筆頭,想學會跑就必須先學會好好走路。在總結的時候確實很頭疼,因為Handler的原理是需要通過源代碼才能說的清楚的,而且它處理機制比較復雜,一時不知道該從哪里說起。想來想去,就先從Handler的幾個簡單的使用方法開始吧,而且在總結過程中為了方便以后快捷的查閱使用,盡量說的精煉,不牽涉到源碼的追蹤和解析。
一、Handler是什么
Handler是android.os包下的一個消息處理的類。
自己寫代碼的時候也將經常使用到Handler,但是對於Handler究竟是什么,還真說不出個所以然。Handler到底是什么呢?如下:
Handler是android為我們封裝的一套消息處理的機制,也是一套子線程用來更新UI的機制
因此,可以知道,Handler可以做兩件事,第一可以在子線程中更新UI,第二可以用來處理消息。下面我們就利用Handler的API,舉一個簡單的小例子,來看一看Handler是怎么處理消息和更新UI的。
二、Handler使用的l一個小例子以及相應的方法總結
(1)模擬圖片輪播效果
大家在點擊淘寶的時候肯定遇到過淘寶為你推薦商品的情況,而且推薦的圖片會快速的一張接一張的不斷的更換。現在我們就用Handeler中的postDelayed方法來簡單模擬這樣子的一個圖片輪播的效果。大家可以翻看源碼的注釋,這個方法是用來延遲發送一個Runnable實例的,也就是延遲執行該Runnable里的run方法。
首先你要准備三張圖片(請讀者自行准備),然后新建項目“HandlerTest”,在其activity_main.xml中寫入如下代碼:
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 > 6 7 <ImageView 8 android:id="@+id/imgview" 9 android:layout_width="wrap_content" 10 android:layout_height="wrap_content" 11 android:src="@drawable/ali"/> 12 13 </LinearLayout>
代碼很簡單,就是放置了一個ImageView用來顯示圖片而已。然后在MainActivity中寫入下面的代碼:
1 package com.example.handldertest; 2 3 import android.os.Bundle; 4 import android.os.Handler; 5 import android.widget.ImageView; 6 import android.app.Activity; 7 8 9 public class MainActivity extends Activity { 10 11 private ImageView img; 12 //實例化圖片數組,存放的是他們的id 13 private int[] imgs = {R.drawable.ali,R.drawable.girl,R.drawable.q}; 14 private int index = 0; 15 16 private Handler mHandler = new Handler(); 17 private MyRunnable mr = new MyRunnable(); 18 19 class MyRunnable implements Runnable{ 20 21 public void run() { 22 index++; 23 index = index%3; 24 25 img.setImageResource(imgs[index]); 26 27 mHandler.postDelayed(mr, 1000); 28 29 } 30 31 } 32 33 protected void onCreate(Bundle savedInstanceState) { 34 super.onCreate(savedInstanceState); 35 setContentView(R.layout.activity_main); 36 img = (ImageView) findViewById(R.id.imgview); 37 38 mHandler.postDelayed(mr, 1000); 39 } 40 41 }
然后我們是怎么首先圖片輪播的呢?其實很簡單,我們在主線程中postDelayed一個mr對象,然后再在mr對象的run方法中,然它將自己再postDelayed,這樣子它就無限循環下去了。那么run方法也就無限循環了,我們只要在run方法中執行ImageView的圖片顯示邏輯即可。運行程序,效果如下圖:
(2)Handler常用的一個方法小結
相信這些方法大家都不會感到陌生,在Handler的API中都是可以查閱到的。現小結如下:
postDelayed(Runnable r, long delayMillis) 延遲多少秒后直接會執行Runnable里的run方法
sendEmptyMessage(int what) 直接發送一個只包含what字段的消息
sendMessage(Message msg) 發送一個Message對象
removeCallbacks(Runnable r) 從Handler中移除一個Runnable對象
removeMessages(int what)
從Handler中移除一個what字段的消息
上面的方法的使用應該是很熟悉的了,因為經常用到,就不多舉例子了,更多的方法可以查找API文檔。把重點放在Handler的消息處理機制的總結上。這是下一篇文章所要做的內容。