01消息分發(fā)
當(dāng)Message對象被發(fā)送到Handler,并嘗試被處理時检疫,Handler會對消息進(jìn)行分發(fā)九杂,即決定由誰處理消息。
-
在消息機(jī)制中脚线,可以有一下3種處理消息的方式:
【高優(yōu)先級】在創(chuàng)建Message對象時搁胆,調(diào)用Message類的靜態(tài)方法public static Message obtain(Handler h,Runnable callback),指定callback 參數(shù),則由callback處理消息邮绿; 【中等優(yōu)先級】在創(chuàng)建Handler 對象時渠旁,調(diào)用public Handler(Callback callback)構(gòu)造方法,指定callback ,將由Handler.Callback接口中定義的 public boolean handleMessage(Message msg) 方法處理消息船逮; 【低等優(yōu)先級】自定義類繼承Handler類顾腊,創(chuàng)建自定義的Handler對象,并在自定義類中重寫public void handlerMessage(Message msg) 方法挖胃,由重寫的方法處理消息杂靶;
代碼
處理消息方式一
布局部分
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="cn.tedu.third.MainActivity" >
<ProgressBar
android:id="@+id/progressBar1"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="88dp"
android:max="100"
android:progress="0 />
<Button
android:id="@+id/btn_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/progressBar1"
android:layout_centerHorizontal="true"
android:layout_marginTop="70dp"
android:text="更新進(jìn)度"
android:onClick="showProgress"/>
</RelativeLayout>
Activity中
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ProgressBar;
public class MainActivity extends Activity {
private Handler handler;
private ProgressBar pbProgress;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler=new Handler();
pbProgress=(ProgressBar) findViewById(R.id.progressBar1);
}
public void showProgress(View v){
new UpdateProgressThread().start();
}
private class UpdateProgressThread extends Thread{
private int i=0;
@Override
public void run() {
for(;i<100;i++){
Message msg =Message.obtain(handler, new Runnable() {
@Override
public void run() {
pbProgress.setProgress(i+1);
}
});
msg.sendToTarget();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
處理消息方式二
布局部分與上面布局一樣
activity中
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ProgressBar;
public class MainActivity extends Activity {
private ProgressBar pbProgress;
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler=new Handler(new InnerCallBack());
pbProgress=(ProgressBar) findViewById(R.id.progressBar1);
}
public void showProgress(View v){
new UpdateProgressThread().start();
}
private class InnerCallBack implements Callback{
@Override
public boolean handleMessage(Message msg) {
if(MESSAGE_UPDATE_PROGRESS==msg.what){
pbProgress.setProgress(msg.arg1);
}
return false;
}
}
private static final int MESSAGE_UPDATE_PROGRESS = 0;
private class UpdateProgressThread extends Thread{
@Override
public void run() {
for(int i =0 ;i<100;i++){
Message.obtain(handler, MESSAGE_UPDATE_PROGRESS, i+1, 0).sendToTarget();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
處理消息方式三
布局部分與上面布局一樣
activity中
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
public class MainActivity extends Activity {
private ProgressBar pbProgress;
private Handler handler;
private static final int MESSAGE_UPDATE_PROGRESS = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler=new InnerHandler();
pbProgress=(ProgressBar) findViewById(R.id.progressBar1);
}
public void showProgress(View v) {
new UpdateProgressThread().start();
}
private class InnerHandler extends Handler{
@Override
public void handleMessage(Message msg) {
if(MESSAGE_UPDATE_PROGRESS==msg.what){
pbProgress.setProgress(msg.arg1);
}
}
}
private class UpdateProgressThread extends Thread{
@Override
public void run() {
for(int i =0;i<100;i++){
Message.obtain(handler, MESSAGE_UPDATE_PROGRESS, i+1, 0).sendToTarget();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
02.線程通信模型詳解
-
由于向目標(biāo)線程發(fā)送消息的線程可能比較多,為了確保目標(biāo)線程能收到這些消息酱鸭,并逐一處理吗垮,在消息機(jī)制中,存在4中角色:
1.Message :消息的載體凹髓; 2.Handler:發(fā)送消息烁登、處理消息 3.MessageQueue:消息隊(duì)列; 4.Looper:消息隊(duì)列的管理者蔚舀;
Message
Message是消息機(jī)制中信息的載體防泵;
Handler
- Handler用于執(zhí)行消息的發(fā)出和處理;
- Handler關(guān)聯(lián)一個獨(dú)立的線程及消息隊(duì)列蝗敢,即Handler在那個線程創(chuàng)建捷泞,則綁定到那個線程的消息隊(duì)列;
- Handler的創(chuàng)建決定了他所在的線程寿谴,則處理對應(yīng)線程中收到的消息锁右;
MessageQueue
- MessageQueue是Message的容器,它是一個先進(jìn)先出、后進(jìn)后出的隊(duì)列咏瑟;
- 任何Message在被發(fā)出后拂到,都會被先放到MessageQueue中,然后再逐一的發(fā)送給目標(biāo)码泞;
- MessageQueue由Looper實(shí)現(xiàn)管理兄旬,因此,開發(fā)人員無須對其進(jìn)行處理余寥。
Looper
- Looper是MessageQueue的管理者领铐;
- 當(dāng)Message被發(fā)出后,由Looper關(guān)聯(lián)的MessageQueue.IdleHandler將其添加到MessageQueue中宋舷;
- Looper在工作時绪撵,會循環(huán)讀取MessageQueue,然后實(shí)現(xiàn)消息的發(fā)送祝蝠;
- 每個線程都有獨(dú)立的Looper音诈,由各個Looper管理各個線程的消息隊(duì)列;
- Looper必須調(diào)用Prepare()系列方法進(jìn)行初始化绎狭,然后再調(diào)用loop()方法才會開始工作细溅;
- 每個Handler在初始化之前,對應(yīng)的線程中必須有匹配的Looper儡嘶,而主線程默認(rèn)即存在已經(jīng)啟動的Looper谒兄。