Android AsyncChannel源码分析

发布时间:2016-12-8 17:50:05 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"Android AsyncChannel源码分析",主要涉及到Android AsyncChannel源码分析方面的内容,对于Android AsyncChannel源码分析感兴趣的同学可以参考一下。

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 fields mSrcContext = srcContext; mSrcHandler = srcHandler; mSrcMessenger = new Messenger(mSrcHandler); // Initialize destination fields mDstMessenger = 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; @Override public 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() { } @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实现 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); } }

上一篇:极客技术专题【011期】:EasyUI初级教程
下一篇:Mac OS 下libpomelo的安装过程

相关文章

相关评论