AsyncChannel类用于处理两个Handler之间的异步消息传递,消息传递的Handler可以出于同一进程,也可以处于不同进程,不同进程之间的Handler消息传递使用Android的Binder通信机制来实现。
目前,ASyncChannel可以使用两种协议方式: 一对多的通信方式(简单的请求与应答方式) 在此种交互方式下,服务器端并不知道请求来自哪个客户端, 通信前双方不需要显示建立连接。客户端(发送方)将请求发送给服务器(接收方),服务器则通过replayToMessage方法向客户端发送应答消息.
一对一的通信方式 在此种通信模式下,服务器端需要知道当前连接的是哪个客户端,通信双方需要显示建立双向连接。
1.同一进程间的Handler连接
fullyConnectSync函数建立的是进程内的Handler通信
[java]
view plain
copy
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; }
[java]
view plain
copy
public int connectSync(Context srcContext, Handler srcHandler, Handler dstHandler) { return connectSync(srcContext, srcHandler, new Messenger(dstHandler)); }
[java]
view plain
copy
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; }
[java]
view plain
copy
public void connected(Context srcContext, Handler srcHandler, Messenger dstMessenger) { if (DBG) log("connected srcHandler to the dstMessenger E"); mSrcContext = srcContext; mSrcHandler = srcHandler; mSrcMessenger = new Messenger(mSrcHandler); mDstMessenger = dstMessenger; if (DBG) log("connected srcHandler to the dstMessenger X"); }
对于同一进程的handler 通信,如果与连接相关的对象初始化完成了,那就说明双方的连接是没有问题了。如果连接成功就发送 CMD_CHANNEL_FULL_CONNECTION消息,这个消息被发送到 AsyncChannel中的 SyncMessenger,SyncMessenger维护着一个消息栈和消息发送线程。
2.不同进程间的Handler连接
[java]
view plain
copy
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方法
[java]
view plain
copy
final class ConnectAsync implements Runnable { Context mSrcCtx; Handler mSrcHdlr; String mDstPackageName; String mDstClassName; @Override public void run() { int result = connectSrcHandlerToPackageSync(mSrcCtx, mSrcHdlr, mDstPackageName, mDstClassName); replyHalfConnected(result); } }
直接调用connectSrcHandlerToPackageSync函数来实现跨进程Handler连接
[java]
view plain
copy
public int connectSrcHandlerToPackageSync( Context srcContext, Handler srcHandler, String dstPackageName, String dstClassName) { if (DBG) log("connect srcHandler to dst Package & class E"); mConnection = new AsyncChannelConnection(); mSrcContext = srcContext; mSrcHandler = srcHandler; mSrcMessenger = new Messenger(srcHandler); mDstMessenger = null; Intent intent = new Intent(Intent.ACTION_MAIN); intent.setClassName(dstPackageName, dstClassName); 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函数
[java]
view plain
copy
class AsyncChannelConnection implements ServiceConnection { AsyncChannelConnection() { } @Override public void onServiceConnected(ComponentName className, IBinder service) { mDstMessenger = new Messenger(service); replyHalfConnected(STATUS_SUCCESSFUL); } @Override public void onServiceDisconnected(ComponentName className) { replyDisconnected(STATUS_SUCCESSFUL); } }
3. 消息同步发送
AsyncChannel提供了sendMessageSynchronously消息同步发送接口,该函数由AsyncChannel的内部类SyncMessenger实现
[java]
view plain
copy
public Message sendMessageSynchronously(int what) { Message msg = Message.obtain(); msg.what = what; Message resultMsg = sendMessageSynchronously(msg); return resultMsg; }
[java]
view plain
copy
public Message sendMessageSynchronously(Message msg) { Message resultMsg = SyncMessenger.sendMessageSynchronously(mDstMessenger, msg); return resultMsg; }
直接调用内部类SyncMessenger的成员sendMessageSynchronously函数来发送一个同步消息
[java]
view plain
copy
private static Message sendMessageSynchronously(Messenger dstMessenger, Message msg) { 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; } 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实例。
[java]
view plain
copy
private static SyncMessenger obtain() { SyncMessenger sm; synchronized (sStack) { if (sStack.isEmpty()) { sm = new SyncMessenger(); sm.mHandlerThread = new HandlerThread("SyncHandler-" + sCount++); sm.mHandlerThread.start(); 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.消息异步发送
[java]
view plain
copy
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); }
[java]
view plain
copy
public void sendMessage(Message msg) { msg.replyTo = mSrcMessenger; try { mDstMessenger.send(msg); } catch (RemoteException e) { replyDisconnected(STATUS_SEND_UNSUCCESSFUL); } }
转自于:
http://blog.csdn.net/fuyajun01/article/details/45012337
http://blog.csdn.net/yangwen123
顶
0
踩
转载请注明原文地址: https://ju.6miu.com/read-19851.html