Android-线程通讯设计模式-Handler消息模型

Android-线程通讯设计模式-Handler消息模型

问题思考:

1) Android中的工作线程获取数据以后如何传递给主线程? 
例如: 
例如工作线程通过网络下载一张图片,通过主线程将图片更新到页面上。 
所有的耗时操作在工作线程,工作线程不能操作UI 
2) Android 中主线程的数据如何传递给工作线程? 
例如: 
主线程将要下载的文件的名字传递给工作线程。 
记住:工作线程是不能更新UI的 
目的:尽量不要去阻塞主线程,安卓中的UI运行在主线程。 
3)SendMessage与PostMessage的区别: 
前者同步,后者异步。 
SendMessage发送消息后会等对方处理完这个消息后才会继续! 
PostMessage则将消息发送出去后就会继续! 
所以注意,不要通过PostMessage传递临时变量指针,应该很可能消息被处理时该变量已经销毁,这时访问就会出错 
4)handleMessage与dispatchMessage处理消息的区别? 
handleMessage处理消息在主线程中 
dispatchMessage处理消息相当新开了一个线程中

用SendMessage替换DispatchMessage不会有问题,但是效率没有DispatchMessage高 
但是用DispatchMessage替换SendMessage却不行!

dispatchMessage是新开了一个线程,而sendMessage是在主线程,所以更新UI的时候报错了,这也应证了安卓只能在主线程更新UI这一情况了。

Android中线程通讯底层消息模型

Handler给哪个线程发消息,就关联哪个线程的looper(双向关联!)

注:此章是为了个人能更好的理解Android底层机制

Android中线程之间进行数据传递通常要借助消息模型,在这个消息模型中会设计到如下几个对象:

  • Message(消息对象):数据的载体

  • MessageQueue(消息队列):存储多个消息对象

  • Looper(迭代器对象):迭代消息队列

  • Handler(消息处理对象)发送,处理消息



简单案例不涉及主线程与工作线程!


class Message{
    Object obj;

    @Override
    public String toString() {
        return "Message [obj=" + obj + "]";
    }

}
class MessageQueue{
    private BlockingQueue<Message> queue=
            new ArrayBlockingQueue<>(10);
    public void put(Message msg){//放消息
        try{
            queue.put(msg);
        }catch(Exception e){}
    }
    public Message take(){//取消息
        try {
            return queue.take();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
class Looper{
    private MessageQueue mq;
    //Looper关联MessageQueue(MessageQueue的生命周期随looper变化而变化,这是强聚合)
    //Looper关联Handler(通过set等方法的是低聚合)
    //注:能从Looper中关联Handler,也能从Handler中关联looper,这是双向关联!

    private Handler handler;
    public void setHandler(Handler handler) {
        this.handler = handler;
    }
    public MessageQueue getMq() {
        return mq;
    }
    boolean flag=true;
    public Looper(){
        mq=new MessageQueue();//强聚合(组合)
    }
    public void loop(){
        while(flag){
            //迭代消息队列
            Message msg=mq.take();
            //调用handler方法处理消息
            handler.handleMessage(msg);
        }
    }
}
class Handler{
    //Hanlder关联looper(has a),获取消息队列
    private Looper looper;
    public Handler(Looper looper){
        this.looper=looper;
        looper.setHandler(this);
    }
    //Handler与Message的关系是use a
    public void sendMessage(Message msg){
        //将消息存储到消息队列
        looper.getMq().put(msg);
    }
    public void handleMessage(Message msg){
        //处理消息队列中的消息
        System.out.println(msg);
    }
}
public class TestMsg {

    public static void main(String[] args) {
        //消息对象
        Message msg1=new Message();
        msg1.obj="helloworld";
        //迭代器对象(此对象创建时会创建消息队列)
        Looper looper=new Looper();
        Handler h=new Handler(looper);
        h.sendMessage(msg1);
        Message msg2=new Message();
        msg2.obj="gsd1504";
        h.sendMessage(msg2);
        looper.loop();
    }
}

主线程与工作线程配合案例

class Message{
    Object obj;

    @Override
    public String toString() {
        return "Message [obj=" + obj + "]";
    }

}
class MessageQueue{
    private BlockingQueue<Message> queue=
            new ArrayBlockingQueue<>(10);
    public void put(Message msg){//放消息
        try{
            queue.put(msg);
        }catch(Exception e){}
    }
    public Message take(){//取消息
        try {
            return queue.take();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
class Looper{
    private MessageQueue mq;
    private Handler handler;
    public void setHandler(Handler handler) {
        this.handler = handler;
    }
    public MessageQueue getMq() {
        return mq;
    }
    boolean flag=true;
    public Looper(){
        mq=new MessageQueue();//强聚合(组合)
    }
    public void loop(){
        while(flag){
            //迭代消息队列
            Message msg=mq.take();
            //调用handler方法处理消息
            handler.handleMessage(msg);
        }
    }
}
class Handler{
    private Looper looper;
    public Handler(Looper looper){
        this.looper=looper;
        looper.setHandler(this);
    }
    public void sendMessage(Message msg){
        //将消息存储到消息队列
        looper.getMq().put(msg);
    }
    public void handleMessage(Message msg){
        //处理消息队列中的消息
        System.out.println(msg);
    }
}
public class TestMsg {
    static Looper looper;
    /**主线程给工作线程发消息*/
    public static void main(String[] args) {
        //消息对象
        Message msg1=new Message();
        msg1.obj="helloworld";
        //迭代器对象(此对象创建时会创建消息队列)
        new Thread(){
            public void run() {
                //looper共享数据集加锁
                synchronized (TestMsg.class) {
                    looper=new Looper();
                    TestMsg.class.notify();//类对象
                }
                looper.loop();
            };
        }.start();
        synchronized (TestMsg.class) {
//Hanlder关联那个线程的looper,就给哪个线程发消息
//也就是主线程给工作线程发消息
            if(looper==null)try{TestMsg.class.wait();}catch(Exception e){}
            Handler h=new Handler(looper);
            h.sendMessage(msg1);
        }
    }
}
//给哪个线程发消息就让handler关联哪个线程的looper


提取类封装拿到looper案例 
HandlerThread类:
public class HandlerThread extends Thread{

    Looper looper;
    @Override
    public void run() {
        synchronized (this) {
            looper=new Looper();
            this.notify();
        }
        looper.loop();
    }

    public Looper getLooper(){
        synchronized (this) {
            if(looper==null)
                try{this.wait();}catch(Exception e){e.printStackTrace();}
            return looper;
        }
    }
    //一个方法运行在哪个线程取决于此方法在哪个线程被调用的
}


TestMsg类


class Message{
    Object obj;

    @Override
    public String toString() {
        return "Message [obj=" + obj + "]";
    }

}
class MessageQueue{
    private BlockingQueue<Message> queue=
            new ArrayBlockingQueue<>(10);
    public void put(Message msg){//放消息
        try{
            queue.put(msg);
        }catch(Exception e){}
    }
    public Message take(){//取消息
        try {
            return queue.take();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
class Looper{
    private MessageQueue mq;
    private Handler handler;
    public void setHandler(Handler handler) {
        this.handler = handler;
    }
    public MessageQueue getMq() {
        return mq;
    }
    boolean flag=true;
    public Looper(){
        mq=new MessageQueue();//强聚合(组合)
    }
    public void loop(){
        while(flag){
            //迭代消息队列
            Message msg=mq.take();
            //调用handler方法处理消息
            handler.handleMessage(msg);
        }
    }
}
class Handler{
    private Looper looper;
    public Handler(Looper looper){
        this.looper=looper;
        looper.setHandler(this);
    }
    public void sendMessage(Message msg){
        //将消息存储到消息队列
        looper.getMq().put(msg);
    }
    public void handleMessage(Message msg){
        //处理消息队列中的消息
        System.out.println(msg);
    }
}
public class TestMsg {
    /**主线程给工作线程发消息*/
    public static void main(String[] args) {
        //消息对象
        Message msg1=new Message();
        msg1.obj="helloworld";
        //迭代器对象(此对象创建时会创建消息队列)
        HandlerThread ht=new HandlerThread();
        ht.start();
        System.out.println("start");
        Handler h=new Handler(ht.getLooper());
        System.out.println("h="+h);
        h.sendMessage(msg1);

    }
}
//给哪个线程发消息就让handler关联哪个线程的looper





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值