您的位置:首页 > 移动开发 > Android开发

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

2017-12-27 16:35 435 查看

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.t
4000
ake();
//调用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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: