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:消息队列的管理者;
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。