AsyncChannel的使用和原理(原)

本文详细探讨了Android中的AsyncChannel,包括其在进程间通信中的作用、特点、两种工作模式及其使用方法。此外,还深入解析了AsyncChannel的内部机制,包括消息的异步和同步派发,为理解其工作原理提供了清晰的路径。
摘要由CSDN通过智能技术生成

        本文主要介绍AsyncChannel的使用和内部原理。


一、AsyncChannel概述

        

        AsyncChannel在Wifi的处理机制中被大量使用,但是可惜的是该工具是一个internal的方法,没有开放给第三方应用使用,但是该工具提供的思路很有用,可以被扩展到任意两个Handle间传输数据的通道。

        那么AsyncChannel究竟是什么工具呢?他的内部机制又是怎么样呢?
        我们先来看一下AsyncChannel的官方描述:
        * <p>An asynchronous channel between two handlers.</p>
        * <p>The handlers maybe in the same process or in another process. There
        * are two protocol styles that can be used with an AysncChannel. The
        * first is a simple request/reply protocol where the server does
        * not need to know which client is issuing the request.</p>


        * <p>In a simple request/reply protocol the client/source sends requests to the
        * server/destination. And the server uses the replyToMessage methods.
        * In this usage model there is no need for the destination to
        * use the connect methods. The typical sequence of operations is:</p>


        * <p>A second usage model is where the server/destination needs to know
        * which client it's connected too. For example the server needs to
        * send unsolicited messages back to the client. Or the server keeps
        * different state for each client. In this model the server will also
        * use the connect methods. The typical sequence of operation is:</p>
        以上是AsyncChannel文件头的描述,从这三段描述中我们可以大致知道AsyncChannel的作用、特点以及用法。

1.1、作用

        AsyncChannel在两个Handler间搭建了通道,可以用于消息传输。


1.2、特点


        从上面第一段英文描述可以知道AsyncChannel的两个特点:

        1、AsyncChannel可以作为Handler之间的通道。

        2、这两个Handler可以处于同一个进程,也可以不再同一个进程。


1.3、两种工作模式


        第二段和第三段英文分别描述了AsyncChannel的两种工作模式:

        1、单项通道模式,在该模式下,客户端只能向服务端发起请求,服务端给出回应。
        2、双向通道模式,在该模式下,客户端和服务端同时连接上AsyncChannel,客户端可以向服务端发送请求,服务端也可以向客户端发送请求。

        下面我们分别来介绍这两种模式的使用方法。


二、AsyncChannel通道使用方法

        

        为了进行测试,我搭建了一个Demo程序用于测试相关功能,源码可以这里下载。由于AsyncChannel是internal的工具,因此该Demo必须要在ROM源码环境下编译并具备系统签名

        在这个Demo中,只有三个文件:MainActivity、AsyncChannelClient、AsyncChannelService、AsyncChannelServiceFull四个文件,其作用分别是:
        MainActivity
            ----负责界面搭建,里面包含:“初始化客户端和服务端并依次建立单向通道和双向通道”、“初始化客户端和服务端并直接建立双向通道”、“发送异步信息”、“发送同步信息”等四个按钮。
        AsyncChannelClient
            ----作为客户端,向服务端发送请求。
        AsyncChannelService
            ----作为服务端,接受客户端请求。
        AsyncChannelServiceFull
            ----作为服务端,用于接受快速双向通道的请求。

        下面来看AsyncChannel的具体使用。


2.1、单向通道建立方法

        

        在这个Demo中,当点击“初始化客户端和服务端并依次建立单向通道和双向通道”后,就会先后启动服务端和客户端,当客户端的Server启动(onStartCommand)时,就会与服务端建立单项通道。

        我们先来看点击动作的处理:
        @MainActivity.java
        public void onClick(View view) {
            switch (view.getId()) {
                case R.id.start_service_btn: {
                    // 启动客户端和服务端
                    Intent intent = new Intent();
                    intent.setComponent(new ComponentName(this, AsyncChannelService.class));
                    startService(intent);
                    Intent inte = new Intent();
                    inte.setComponent(new ComponentName(this, AsyncChannelClient.class));
                    //Action是"Normal"
                    inte.setAction("Normal");
                    startService(inte);
                    break;
                }
            }
        }
        然后我们来看客户端的 初始化流程:
        @AsyncChannelClient.java
        public static AsyncChannel sClientAsyncChannel;
        public int onStartCommand(Intent intent, int flags, int startId) {
            //创建本地的Handler对象
            HandlerThread handlerThread = new HandlerThread("ClientThread");
            handlerThread.start();
            Handler clientHandler = new ClientHandler(handlerThread.getLooper());
            //创建客户端的AsyncChannel
            sClientAsyncChannel = new AsyncChannel();
            String act = intent.getAction();
            //我们发送的Action就是"Normal"
            if ("Normal".equals(act)) {
                // 建立单向通道,获取服务端的Messenger对象
                Messenger serviceMessenger = AsyncChannelService.getServiceMessenger();
                //发起连接请求
                sClientAsyncChannel.connect(this, clientHandler, serviceMessenger);
            } else if ("Fast".equals(act)) {
            }
            return super.onStartCommand(intent, flags, startId);
        }
        上面的过程中,通过客户端的getServiceMessenger()方法 拿到服务端的Messenger对象,其过程是:
        @AsyncChannelService.java
        public static Messenger getServiceMessenger() {
            //服务端需要用自己的Handler构建Messenger然后发送给客户端
            return new Messenger(mServiceHandler);
        }
        以上就是客户端所做的全部准备,以及发起创建通道的请求过程。从这个过程中我们看到,作为客户端,如果想要创建与服务端之间的AsyncChannel,需要做以下几个准备:
        1、获取服务端的Messenger对象,该对象其实就是利用服务端的Handler构建的Messenger;
        2、创建客户端自己的Handler对象;
        3、创建AsyncChannel对象;
        4、通过AsyncChannel对象,连接当前的Handler和服务端的Messenger,从而申请连接。

        当客户端发送完connect()请求之后,客户端需要做的就是在Handler对象中等待Message消息:
        @AsyncChannelClient.java
        public void handleMessage(Message message) {
            switch (message.what) {
                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
                    if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
                        Log.d(tag, "Service half connected");
                    }
                    break;
                }
            }
        }
        当客户端接收到AsyncChannel.CMD_CHANNEL_HALF_CONNECTED消息后,说明当前的单项通道建立成功。此时的客户端可以通过sAsyncChannel的sendMessage()方法向服务端发送消息了。

        以上就是单项通道的建立过程,整个过程不需要服务端做任何操作。


2.2、双向通道建立方法


   

  • 10
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值