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


1.同一进程间的Handler连接

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

public int fullyConnectSync(Context srcContext, Handler srcHandler, Handler dstHandler) {int status = connectSync(srcContext, srcHandler, dstHandler);if (status == STATUS_SUCCESSFUL) {Message response = sendMessageSynchronously(CMD_CHANNEL_FULL_CONNECTION);status = response.arg1;}return status;}

public int connectSync(Context srcContext, Handler srcHandler, Handler dstHandler) {return connectSync(srcContext, srcHandler, new Messenger(dstHandler));}

public int connectSync(Context srcContext, Handler srcHandler, Messenger dstMessenger) {if (DBG) log("halfConnectSync srcHandler to the dstMessenger  E");connected(srcContext, srcHandler, dstMessenger);if (DBG) log("halfConnectSync srcHandler to the dstMessenger X");return STATUS_SUCCESSFUL;}

public void connected(Context srcContext, Handler srcHandler, Messenger dstMessenger) {if (DBG) log("connected srcHandler to the dstMessenger  E");// Initialize source fieldsmSrcContext = srcContext;mSrcHandler = srcHandler;mSrcMessenger = new Messenger(mSrcHandler);// Initialize destination fieldsmDstMessenger = dstMessenger;if (DBG) log("connected srcHandler to the dstMessenger X");}
对于同一进程的handler 通信,如果与连接相关的对象初始化完成了,那就说明双方的连接是没有问题了。如果连接成功就发送 CMD_CHANNEL_FULL_CONNECTION消息,这个消息被发送到 AsyncChannel中的 SyncMessenger,SyncMessenger维护着一个消息栈和消息发送线程。

2.不同进程间的Handler连接

public void connect(Context srcContext, Handler srcHandler, String dstPackageName,String dstClassName) {if (DBG) log("connect srcHandler to dst Package & class E");//启动一个连接线程ConnectAsync ca = new ConnectAsync(srcContext, srcHandler, dstPackageName, dstClassName);new Thread(ca).start();if (DBG) log("connect srcHandler to dst Package & class X");}
启动ConnectAsync线程后,执行该线程中的run方法

final class ConnectAsync implements Runnable {Context mSrcCtx;Handler mSrcHdlr;String mDstPackageName;String mDstClassName;@Overridepublic void run() {int result = connectSrcHandlerToPackageSync(mSrcCtx, mSrcHdlr, mDstPackageName,mDstClassName);replyHalfConnected(result);}}
直接调用connectSrcHandlerToPackageSync函数来实现跨进程Handler连接

public int connectSrcHandlerToPackageSync(Context srcContext, Handler srcHandler, String dstPackageName, String dstClassName) {if (DBG) log("connect srcHandler to dst Package & class E");mConnection = new AsyncChannelConnection();/* Initialize the source information */mSrcContext = srcContext;mSrcHandler = srcHandler;mSrcMessenger = new Messenger(srcHandler);mDstMessenger = null;/* Send intent to create the connection */Intent intent = new Intent(Intent.ACTION_MAIN);intent.setClassName(dstPackageName, dstClassName);//通过绑定服务来实现不同进程间的Handler连接boolean result = srcContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);if (DBG) log("connect srcHandler to dst Package & class X result=" + result);return result ? STATUS_SUCCESSFUL : STATUS_BINDING_UNSUCCESSFUL;}
AsyncChannelConnection实现了ServiceConnection接口,在服务成功连接上时,自动调用onServiceConnected函数
class AsyncChannelConnection implements ServiceConnection {AsyncChannelConnection() {}@Overridepublic void onServiceConnected(ComponentName className, IBinder service) {mDstMessenger = new Messenger(service);replyHalfConnected(STATUS_SUCCESSFUL);}@Overridepublic void onServiceDisconnected(ComponentName className) {replyDisconnected(STATUS_SUCCESSFUL);}}

3. 消息同步发送

AsyncChannel提供了sendMessageSynchronously消息同步发送接口,该函数由AsyncChannel的内部类SyncMessenger实现

public Message sendMessageSynchronously(int what) {Message msg = Message.obtain();msg.what = what;Message resultMsg = sendMessageSynchronously(msg);return resultMsg;}

public Message sendMessageSynchronously(Message msg) {Message resultMsg = SyncMessenger.sendMessageSynchronously(mDstMessenger, msg);return resultMsg;}
直接调用内部类SyncMessenger的成员sendMessageSynchronously函数来发送一个同步消息
private static Message sendMessageSynchronously(Messenger dstMessenger, Message msg) {//获取一个SyncMessenger对象SyncMessenger sm = SyncMessenger.obtain();try {if (dstMessenger != null && msg != null) {msg.replyTo = sm.mMessenger;synchronized (sm.mHandler.mLockObject) {//发送消息dstMessenger.send(msg);//等待回复sm.mHandler.mLockObject.wait();}} else {sm.mHandler.mResultMsg = null;}} catch (InterruptedException e) {sm.mHandler.mResultMsg = null;} catch (RemoteException e) {sm.mHandler.mResultMsg = null;}//得到返回的消息,消息是从SyncHandler的handleMessage函数中返回来的Message resultMsg = sm.mHandler.mResultMsg;sm.recycle();return resultMsg;}
SyncMessenger是用来发送同步消息的,通过 sendMessageSynchronously()方法发送消息,并调用了object类的wait方法等待目的handler收到消息后,取出消息中的replyto,然后再用该messenger给SyncMessenger类中的SyncHandler发送消息在该handler的handleMessage方法里面才执行object的notify方法,以保证发送消息的同步性。使用SyncMessenger的静态函数obtain来获取一个SyncMessenger实例。
private static SyncMessenger obtain() {SyncMessenger sm;synchronized (sStack) {if (sStack.isEmpty()) {//创建SyncMessenger对象sm = new SyncMessenger();//创建具有消息循环队列的HandlerThread线程,并启动该线程sm.mHandlerThread = new HandlerThread("SyncHandler-" + sCount++);sm.mHandlerThread.start();//创建SyncHandler对象sm.mHandler = sm.new SyncHandler(sm.mHandlerThread.getLooper());sm.mMessenger = new Messenger(sm.mHandler);} else {sm = sStack.pop();}}return sm;}
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.消息异步发送

public void sendMessage(int what, int arg1, int arg2, Object obj) {Message msg = Message.obtain();msg.what = what;msg.arg1 = arg1;msg.arg2 = arg2;msg.obj = obj;sendMessage(msg);}

public void sendMessage(Message msg) {msg.replyTo = mSrcMessenger;try {mDstMessenger.send(msg);} catch (RemoteException e) {replyDisconnected(STATUS_SEND_UNSUCCESSFUL);}}


更多相关文章

  1. Android通知推送 ——采用MQTT协议实现Android推送
  2. Android(安卓)中如何关闭线程
  3. Android系统中的广播(Broadcast)机制注册注销发送原理总结
  4. Android(安卓)AsyncTask
  5. Android:Handler事件处理机制
  6. Android(安卓)Handler机制之Message的发送与取出
  7. Android消息推送
  8. Android中线程的使用方法
  9. Android(安卓)ANR

随机推荐

  1. Android(安卓)LayoutInflater.inflate 的
  2. Android(安卓)保持屏幕唤醒不熄灭
  3. android中对目录下的文件按时间排序
  4. 解读Android之Service(3)AIDL
  5. android SystemServer详解
  6. 解决ADT中新建Android工程出现多个appcom
  7. android View中如何判断长按事件
  8. Android中由文件名获取文件Id的两种方法
  9. android Paint 渐变色
  10. Android添加依赖出现This support librar