Android AsyncChannel源码分析

    xiaoxiao2021-03-25  109

    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");       // 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连接

    [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();       /* 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函数 [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对象       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实例。 [java]  view plain copy 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.消息异步发送

    [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

    最新回复(0)