Android AsyncChannel源码分析

AsyncChannel类用于处理两个Handler之间的异步消息传递,消息传递的Handler可以出于同一进程,也可以处于不同进程,不同进程之间的Handler消息传递使用Android的Binder通信机制来实现。

目前,ASyncChannel可以使用两种协议方式:
一对多的通信方式(简单的请求与应答方式) 
在此种交互方式下,服务器端并不知道请求来自哪个客户端, 通信前双方不需要显示建立连接。客户端(发送方)将请求发送给服务器(接收方),服务器则通过replayToMessage方法向客户端发送应答消息.

一对一的通信方式 
在此种通信模式下,服务器端需要知道当前连接的是哪个客户端,通信双方需要显示建立双向连接。


1.同一进程间的Handler连接

fullyConnectSync函数建立的是进程内的Handler通信

[java]  view plain copy
  1. public int fullyConnectSync(Context srcContext, Handler srcHandler, Handler dstHandler) {  
  2.     int status = connectSync(srcContext, srcHandler, dstHandler);  
  3.     if (status == STATUS_SUCCESSFUL) {  
  4.         Message response = sendMessageSynchronously(CMD_CHANNEL_FULL_CONNECTION);  
  5.         status = response.arg1;  
  6.     }  
  7.     return status;  
  8. }  
[java]  view plain copy
  1. public int connectSync(Context srcContext, Handler srcHandler, Handler dstHandler) {  
  2.     return connectSync(srcContext, srcHandler, new Messenger(dstHandler));  
  3. }  
[java]  view plain copy
  1. public int connectSync(Context srcContext, Handler srcHandler, Messenger dstMessenger) {  
  2.     if (DBG) log("halfConnectSync srcHandler to the dstMessenger  E");  
  3.     connected(srcContext, srcHandler, dstMessenger);  
  4.     if (DBG) log("halfConnectSync srcHandler to the dstMessenger X");  
  5.     return STATUS_SUCCESSFUL;  
  6. }  
[java]  view plain copy
  1. public void connected(Context srcContext, Handler srcHandler, Messenger dstMessenger) {  
  2.     if (DBG) log("connected srcHandler to the dstMessenger  E");  
  3.     // Initialize source fields  
  4.     mSrcContext = srcContext;  
  5.     mSrcHandler = srcHandler;  
  6.     mSrcMessenger = new Messenger(mSrcHandler);  
  7.     // Initialize destination fields  
  8.     mDstMessenger = dstMessenger;  
  9.     if (DBG) log("connected srcHandler to the dstMessenger X");  
  10. }  
对于同一进程的handler 通信,如果与连接相关的对象初始化完成了,那就说明双方的连接是没有问题了。如果连接成功就发送 CMD_CHANNEL_FULL_CONNECTION消息,这个消息被发送到 AsyncChannel中的 SyncMessenger,SyncMessenger维护着一个消息栈和消息发送线程。

2.不同进程间的Handler连接

[java]  view plain copy
  1. public void connect(Context srcContext, Handler srcHandler, String dstPackageName,  
  2.     String dstClassName) {  
  3.     if (DBG) log("connect srcHandler to dst Package & class E");  
  4.     //启动一个连接线程  
  5.     ConnectAsync ca = new ConnectAsync(srcContext, srcHandler, dstPackageName, dstClassName);  
  6.     new Thread(ca).start();  
  7.     if (DBG) log("connect srcHandler to dst Package & class X");  
  8. }  
启动ConnectAsync线程后,执行该线程中的run方法
[java]  view plain copy
  1. final class ConnectAsync implements Runnable {  
  2.     Context mSrcCtx;  
  3.     Handler mSrcHdlr;  
  4.     String mDstPackageName;  
  5.     String mDstClassName;  
  6.       
  7.     @Override  
  8.     public void run() {  
  9.         int result = connectSrcHandlerToPackageSync(mSrcCtx, mSrcHdlr, mDstPackageName,  
  10.                 mDstClassName);  
  11.         replyHalfConnected(result);  
  12.     }  
  13. }  
直接调用connectSrcHandlerToPackageSync函数来实现跨进程Handler连接
[java]  view plain copy
  1. public int connectSrcHandlerToPackageSync(  
  2.         Context srcContext, Handler srcHandler, String dstPackageName, String dstClassName) {  
  3.     if (DBG) log("connect srcHandler to dst Package & class E");  
  4.     mConnection = new AsyncChannelConnection();  
  5.     /* Initialize the source information */  
  6.     mSrcContext = srcContext;  
  7.     mSrcHandler = srcHandler;  
  8.     mSrcMessenger = new Messenger(srcHandler);  
  9.     mDstMessenger = null;  
  10.     /* Send intent to create the connection */  
  11.     Intent intent = new Intent(Intent.ACTION_MAIN);  
  12.     intent.setClassName(dstPackageName, dstClassName);  
  13.     //通过绑定服务来实现不同进程间的Handler连接  
  14.     boolean result = srcContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);  
  15.     if (DBG) log("connect srcHandler to dst Package & class X result=" + result);  
  16.     return result ? STATUS_SUCCESSFUL : STATUS_BINDING_UNSUCCESSFUL;  
  17. }  
AsyncChannelConnection实现了ServiceConnection接口,在服务成功连接上时,自动调用onServiceConnected函数
[java]  view plain copy
  1. class AsyncChannelConnection implements ServiceConnection {  
  2.     AsyncChannelConnection() {  
  3.     }  
  4.     @Override  
  5.     public void onServiceConnected(ComponentName className, IBinder service) {  
  6.         mDstMessenger = new Messenger(service);  
  7.         replyHalfConnected(STATUS_SUCCESSFUL);  
  8.     }  
  9.     @Override  
  10.     public void onServiceDisconnected(ComponentName className) {  
  11.         replyDisconnected(STATUS_SUCCESSFUL);  
  12.     }  
  13. }  

3. 消息同步发送

AsyncChannel提供了sendMessageSynchronously消息同步发送接口,该函数由AsyncChannel的内部类SyncMessenger实现
[java]  view plain copy
  1. public Message sendMessageSynchronously(int what) {  
  2.     Message msg = Message.obtain();  
  3.     msg.what = what;  
  4.     Message resultMsg = sendMessageSynchronously(msg);  
  5.     return resultMsg;  
  6. }  
[java]  view plain copy
  1. public Message sendMessageSynchronously(Message msg) {  
  2.     Message resultMsg = SyncMessenger.sendMessageSynchronously(mDstMessenger, msg);  
  3.     return resultMsg;  
  4. }  
直接调用内部类SyncMessenger的成员sendMessageSynchronously函数来发送一个同步消息
[java]  view plain copy
  1. private static Message sendMessageSynchronously(Messenger dstMessenger, Message msg) {  
  2.     //获取一个SyncMessenger对象  
  3.     SyncMessenger sm = SyncMessenger.obtain();  
  4.     try {  
  5.         if (dstMessenger != null && msg != null) {  
  6.             msg.replyTo = sm.mMessenger;  
  7.             synchronized (sm.mHandler.mLockObject) {  
  8.                 //发送消息  
  9.                 dstMessenger.send(msg);  
  10.                 //等待回复  
  11.                 sm.mHandler.mLockObject.wait();  
  12.             }  
  13.         } else {  
  14.             sm.mHandler.mResultMsg = null;  
  15.         }  
  16.     } catch (InterruptedException e) {  
  17.         sm.mHandler.mResultMsg = null;  
  18.     } catch (RemoteException e) {  
  19.         sm.mHandler.mResultMsg = null;  
  20.     }  
  21.     //得到返回的消息,消息是从SyncHandler的handleMessage函数中返回来的  
  22.     Message resultMsg = sm.mHandler.mResultMsg;  
  23.     sm.recycle();  
  24.     return resultMsg;  
  25. }  
SyncMessenger是用来发送同步消息的,通过 sendMessageSynchronously()方法发送消息,并调用了object类的wait方法等待目的handler收到消息后,取出消息中的replyto,然后再用该messenger给SyncMessenger类中的SyncHandler发送消息在该handler的handleMessage方法里面才执行object的notify方法,以保证发送消息的同步性。使用SyncMessenger的静态函数obtain来获取一个SyncMessenger实例。
[java]  view plain copy
  1. private static SyncMessenger obtain() {  
  2.     SyncMessenger sm;  
  3.     synchronized (sStack) {  
  4.         if (sStack.isEmpty()) {  
  5.             //创建SyncMessenger对象  
  6.             sm = new SyncMessenger();  
  7.             //创建具有消息循环队列的HandlerThread线程,并启动该线程  
  8.             sm.mHandlerThread = new HandlerThread("SyncHandler-" + sCount++);  
  9.             sm.mHandlerThread.start();  
  10.             //创建SyncHandler对象  
  11.             sm.mHandler = sm.new SyncHandler(sm.mHandlerThread.getLooper());  
  12.             sm.mMessenger = new Messenger(sm.mHandler);  
  13.         } else {  
  14.             sm = sStack.pop();  
  15.         }  
  16.     }  
  17.     return sm;  
  18. }  
SyncMessenger作为一个辅助类,包含了一个线程HandlerThread 的实例mHandlerThread、处理msg的类SyncHandler(Handler的子类)的实例mHandler、接收msg的Messenger实例mMessenger。也就是说,发送给Messenger的消息msg将由SyncHandler来处理,这个处理过程运行在线程HandlerThread中。

同步发送机制:调用者利用SyncMessenger的成员sendMessageSynchronously将要发送的消息msg送往dstMessenger所在的目的进程,由dstMessenger的handler进行处理,然后消息发送线程等待,dstMessenger的handler处理完毕接收到的消息后,要向msg.replyTo回送消息,这时由SyncHandler的handleMessage来处理该回复消息,它将唤醒在消息发送线程中等待的sendMessageSynchronously。从目的进程返回的msg在SyncHandler的handleMessage中拷贝给SyncHandler的mResultMsg,然后由sendMessageSynchronously返回给调用者。

4.消息异步发送

[java]  view plain copy
  1. public void sendMessage(int what, int arg1, int arg2, Object obj) {  
  2.     Message msg = Message.obtain();  
  3.     msg.what = what;  
  4.     msg.arg1 = arg1;  
  5.     msg.arg2 = arg2;  
  6.     msg.obj = obj;  
  7.     sendMessage(msg);  
  8. }  
[java]  view plain copy
  1. public void sendMessage(Message msg) {  
  2.     msg.replyTo = mSrcMessenger;  
  3.     try {  
  4.         mDstMessenger.send(msg);  
  5.     } catch (RemoteException e) {  
  6.         replyDisconnected(STATUS_SEND_UNSUCCESSFUL);  
  7.     }  
  8. }  

转自于:

http://blog.csdn.net/fuyajun01/article/details/45012337

http://blog.csdn.net/yangwen123





0

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值