01消息分發
當Message對象被發送到Handler,并嘗試被處理時,Handler會對消息進行分發,即決定由誰處理消息。
-
在消息機制中,可以有一下3種處理消息的方式:
【高優先級】在創建Message對象時,調用Message類的靜態方法public static Message obtain(Handler h,Runnable callback),指定callback 參數,則由callback處理消息; 【中等優先級】在創建Handler 對象時,調用public Handler(Callback callback)構造方法,指定callback ,將由Handler.Callback接口中定義的 public boolean handleMessage(Message msg) 方法處理消息; 【低等優先級】自定義類繼承Handler類,創建自定義的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="更新進度"
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.線程通信模型詳解
-
由于向目標線程發送消息的線程可能比較多,為了確保目標線程能收到這些消息,并逐一處理,在消息機制中,存在4中角色:
1.Message :消息的載體; 2.Handler:發送消息、處理消息 3.MessageQueue:消息隊列; 4.Looper:消息隊列的管理者;
c.png
Message
Message是消息機制中信息的載體;
Handler
- Handler用于執行消息的發出和處理;
- Handler關聯一個獨立的線程及消息隊列,即Handler在那個線程創建,則綁定到那個線程的消息隊列;
- Handler的創建決定了他所在的線程,則處理對應線程中收到的消息;
MessageQueue
- MessageQueue是Message的容器,它是一個先進先出、后進后出的隊列;
- 任何Message在被發出后,都會被先放到MessageQueue中,然后再逐一的發送給目標;
- MessageQueue由Looper實現管理,因此,開發人員無須對其進行處理。
Looper
- Looper是MessageQueue的管理者;
- 當Message被發出后,由Looper關聯的MessageQueue.IdleHandler將其添加到MessageQueue中;
- Looper在工作時,會循環讀取MessageQueue,然后實現消息的發送;
- 每個線程都有獨立的Looper,由各個Looper管理各個線程的消息隊列;
- Looper必須調用Prepare()系列方法進行初始化,然后再調用loop()方法才會開始工作;
- 每個Handler在初始化之前,對應的線程中必須有匹配的Looper,而主線程默認即存在已經啟動的Looper。