Handler消息传递机制
我们知道当一个Andorid程序第一次启动时,Andorid会调用一条主线程,用这条主线程来负责管理UI组件,所以我们也称它为UI线程。并且Andorid平台只允许UI线程来管理Activity中的UI组件。这样导致了新启动的线程没办法动态的改变系统中的UI组件,为了解决这个麻烦 Andorid使用了Handler消息传递机制。
Handler的主要作用
- 在新启动的线程中发送消息
- 在主线程中获取、处理消息
Handler包含了如下方法用来处理消息:
void handlerMessage(Message msg):处理消息的方法
final boolean hasMessage(int what):查看消息队列中what指定值时候存在
final boolean hasMessage(int what, Object object):查看消息队列中时候有what和object指定值得消息
Message obtainMessage():获取消息
sendEmptyMessage(int what):发送空消息,其中what是属性
来看一个Handler实例
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Intent;
import android.util.Log;
import android.view.View;
import android.app.Activity;
import android.widget.Button;
import android.widget.Toast;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.first);
//创建一个Handler对象,重写handleMessage方法
final Handler myHandler = new Handler(){
@Override
public void handleMessage(Message message){
//这里来写要让系统做什么
if (message.what == 0x1233){
Log.v("Tag", "12331");
}
}
};
//定义一个计时器,周期性的发送空消息
new Timer().schedule(new TimerTask() {
@Override
public void run() {
//what属性是估计这么设置的,当然你也可以随意设置
myHandler.sendEmptyMessage(0x1233);
}
},0,200);
}
}
程序的结果:
03-09 21:23:38.233 4177-4177/com.example.administrator.itentlearn V/Tag: 12331
03-09 21:23:38.436 4177-4177/com.example.administrator.itentlearn V/Tag: 12331
03-09 21:23:38.638 4177-4177/com.example.administrator.itentlearn V/Tag: 12331
03-09 21:23:38.838 4177-4177/com.example.administrator.itentlearn V/Tag: 12331
03-09 21:23:39.038 4177-4177/com.example.administrator.itentlearn V/Tag: 12331
03-09 21:23:39.239 4177-4177/com.example.administrator.itentlearn V/Tag: 12331
03-09 21:23:39.439 4177-4177/com.example.administrator.itentlearn V/Tag: 12331
当然你也可以用他来修改UI组件,直接写在handleMessage方法中就可以。
注意:在Androdi中新线程想要修改UI组件只有通过Handler重写handleMessage方法!
Andorid中文API:Handler
Handler的工作原理
首先介绍一下Handler的几个工作组件:
- Message:Handler用来接收和处理消息的对象
- Looper:每个线程都拥有一个Looper,它的作用是负责读取MessageQueue中的消息,每当读到消息就传递给Handler来处理
- MessageQueue:消息队列,存取方式是先进先出,每当创建一个Looper对象时,在Looper的对象中会自动创建一个MessageQueue对象。
大家来看源码:
private Looper(){
mQueue = new MessageQueue();
mRun = true;
mThread = Thread.currentThread();
}
这个构造器的修饰符是privata,所以不能直接创建这个Looper对象。要创建Looper对象要通过调用它的prapare()方法。
public static final void prepare(){
if(sThreadLocal.get() != null){
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
}
所以Handler的工作原理是这样的:
Hanldler首先发送或接受消息,在发送消息的时候,消息被送到指定的MessageQueue.而MessageQueue是由Looper来负责管理的,Looper使用方法不断的从MessageQueue中取出消息,并且把消息发给对应的Handler来处理。
总而言之就是这三个的各自作用如下:
-Looper:每个线程只有一个Looper,它负责管理MessageQueue,不断的从中读取消息,并且发给对应的Handler来处理
-MessageQueue:由Looer负责管理,采用先进先出的方式来管理Queue
-Handler:能够发送消息去MessageQueue,并且能够处理来自Looper的消息