android 循环机制,Android的消息循环与Handler机制理解

一、概念

1、事件驱动型

什么是事件驱动?就是有事了才去处理,没事就躺着不动。假如把用户点击按钮,滑动页面等这些都看作事件,事件产生后程序就执行相应的处理方法,就是属于事件驱动型。

2、消息循环

把需要处理的事件表示成一个消息,并且把这个消息放入一个队列。消息循环就是一循环,for或者while都一样。从消息队列里面取出未处理的消息,然后调用该消息的处理方法。

3、Handler

最开始碰到handler是需要在子线程里面更新UI的时候。android的UI更新只能在主线程中进行,但是在子线程中执行的逻辑又需要更新UI,例如文件下载,在子线程中访问网络下载之后,就是更新下载进度。这个时候就需要使用Hanlder,准确的说是要发送一个进度更新的消息。什么是Handler?我的理解是消息的处理者。create消息对应一个create的Handler,destroy消息对应一个destroy的Handler。

二、实现

只是说说概念太假了,下面就来实现一个简单的消息处理机制。

1、Msg

把产生的事件用消息来表示,数据用各个参数传递。

public class Msg implements Serializable{

//序列化标识

private static final long serialVersionUID = -2414053244664115328L;

//该消息的处理者。

private int handlerId;

//参数。

public Object arg1;

public Object arg2;

//大量参数

public Object array[];

public Msg(int handlerId) {

this.handlerId=handlerId;

}

public void setHandlerId(int handlerId) {

this.handlerId=handlerId;

}

public int getHandleId() {

return handlerId;

}

}

2、Handler

事件的处理者

public abstract class Handler {

//唯一标识,由Looper分配

private int id;

//使用该Handler的Looper

private Looper looper;

public Handler(Looper looper) {

this.looper=looper;

id=looper.addMsgHandler(this);

}

//消息处理函数

abstract public boolean handleMsg(Msg msg);

//添加一个未处理消息。

public void sendMsg(Msg msg) {

looper.addMsg(msg);

}

//返回该handler的信使。

public Msg obtainMsg() {

return new Msg(id);

}

}

3、Looper

消息循环

import java.util.HashMap;

import java.util.LinkedList;

import java.util.Map;

import java.util.Queue;

public class Looper {

private int handlerCount=0;

//消息队列。

private Queue msgQueue=new LinkedList();

//消息的处理。

private Map msgHandler=new HashMap<>();

//loop

public void loop() {

for(;true;)

if(!msgQueue.isEmpty())

if(!distributeMsg(msgQueue.poll()))

//当消息处理返回false时。程序结束。

break;

}

//添加处理消息的handler

public int addMsgHandler(Handler handler) {

handlerCount++;

msgHandler.put(handlerCount,handler);

return handlerCount;

}

//添加待处理的消息

public void addMsg(Msg msg) {

msgQueue.add(msg);

}

//消息分发

private boolean distributeMsg(Msg msg) {

Handler handler=msgHandler.get(msg.getHandleId());

if(handler!=null) {

handler.handleMsg(msg);

}else {

//出现未知消息,程序结束。

System.out.println("exit");

return false;

}

return true;

}

}

4、模拟生命周期

abstract class Basic{

private Looper mainLooper=new Looper();

private Handler sysHandler=new Handler(mainLooper) {

@Override

public boolean handleMsg(Msg msg) {

if(msg.arg1.equals("create")) {

onCreate();

}

if(msg.arg1.equals("destroy")) {

onDestroy();

}

return true;

}

};

public Basic() {

Msg m=sysHandler.obtainMsg();

m.arg1="create";

sysHandler.sendMsg(m);

//新获取一个Msg,不能沿用上一个。

m=sysHandler.obtainMsg();

m.arg1="destroy";

sysHandler.sendMsg(m);

}

public Looper getMainLooper() {

return mainLooper;

}

/**

* 生命周期

*/

abstract public void onCreate();

abstract public void onDestroy();

}

上面的代码创建了一个抽象类Basic,在里面注册了一个处理create和destroy两个消息的Handler。

5、子线程调用主线程的方法。

public class Main extends Basic{

private final Handler handler

=new Handler(getMainLooper()) {

@Override

public boolean handleMsg(Msg msg) {

// TODO Auto-generated method stub

System.out.println("msg.arg1="+msg.arg1+",Tid="+

Thread.currentThread().getId());

getMainLooper().addMsg(new Msg(-1));

return true;

}

};

public void onCreate() {

System.out.println("..............onCreate");

System.out.println("mainThread Tid="+Thread.currentThread().getId());

new Thread(new Runnable() {

@Override

public void run() {

// TODO Auto-generated method stub

System.out.println("childThread Tid="+Thread.currentThread().getId());

Msg msg=handler.obtainMsg();

msg.arg1="childCall";

handler.sendMsg(msg);

}

}).start();

}

@Override

public void onDestroy() {

// TODO Auto-generated method stub

System.out.println(".............onDestroy");

//getMainLooper().addMsg(new Msg(-1));

}

public static void main(String[] args) {

new Main().getMainLooper().loop();

}

}

6、结果

f6fbe7d036f954d203b1a5d012a21ccc.png

结果分析,首先是两个生命周期的方法被调用,其次是实现了子线程调用主线程的方法。这里子线程转到主线程的原因是因为Looper运行在主线程,消息由Looper分发处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值