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

来源:互联网 发布:测试英语词汇量的软件 编辑:程序博客网 时间:2024/06/06 15:40

思考问题:

原创:http://blog.csdn.net/prince77qiqiqq/article/details/51419871

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
0 0