我是靠谱客的博主 呆萌火,最近开发中收集的这篇文章主要介绍android usb 异步请求理解,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

先贴这个adbtest的例子,用android的usb sdk传输adb协议数据,将android的logcat信息打印再屏幕上。
我研究这个例子的目的是为了实现usb传输tcpip数据,需要借用adb。

http://www.java2s.com/Code/Android/Hardware/USBdevicethatsupportstheadbprotocol.htm

这例子具体有几个类:adbdeviceadbmessage`adbsocket
其中adbdevice是主类,里面有个线程WaitThread主要是用到usb异步读的地方。
huesb异步操作的主要流程是:
1. 调用initialize(UsbDeviceConnection connection, UsbEndpoint endpoint)初始化好1个request,connection是指明连接的,endpoint可以是相应的in或out;
2. 调用queue(ByteBuffer buffer, int length)提交Buffer去读或者写数据;
3. 调用setClientData(Object data)可以做标记,具体作用在下面代码的注释里。
4. 调用usbDeviceConection的requestWait()等待request异步请求生效;注意requestWait()对所有endpoint提交的request都可能生效。很重要的一点是要判断提交的request是否是wait到的request,才能控制不同endpoint的数据流。
贴代码和注释:

        private class WaiterThread extends Thread {
        public boolean mStop;

        public void run() {
            // start out with a command read
            AdbMessage currentCommand = new AdbMessage();
            AdbMessage currentData = null;
            //封装了usbRequest.setClientData和queue,请求读adb协议的command header数据段
            currentCommand.readCommand(getInRequest());

            while (true) {
                synchronized (this) {
                    if (mStop) {
                        return;
                    }
                }
                //阻塞等待request被响应,
                UsbRequest request = mDeviceConnection.requestWait();
                if (request == null) {
                    break;
                }

                AdbMessage message = (AdbMessage)request.getClientData();
                request.setClientData(null);
                AdbMessage messageToDispatch = null;
                /*
                 *为何要如此检查?因为requestWait()等的是所有endpoint提交的request,任何1个都有可能
                 *怎么检查的?在queque的时候,用setclientdata做了标记,然后再比较request的时候,用
                 *getclientdata的结果进行对比
                 */
                if (message == currentCommand) {
                    int dataLength = message.getDataLength();
                    // read data if length > 0
                    if (dataLength > 0) {
                        //请求读adb协议的command data数据段
                        message.readData(getInRequest(), dataLength);
                        currentData = message;
                    } else {
                        messageToDispatch = message;
                    }
                    currentCommand = null;
                //只需关注自己提交的、而不是其他endpoint的 command data request
                } else if (message == currentData) {
                    messageToDispatch = message;
                    currentData = null;
                }
                //command data字段 准备解析并处理
                if (messageToDispatch != null) {
                    // queue another read first
                    //先提交一次read command header, 为下一次接收做准备
                    currentCommand = new AdbMessage();
                    currentCommand.readCommand(getInRequest());

                    // then dispatch the current message
                    dispatchMessage(messageToDispatch);
                }

                // put request back into the appropriate pool
                //in or out request用完了 重新放回List中;       
                if (request.getEndpoint() == mEndpointOut) {
                    releaseOutRequest(request);
                } else {
                    synchronized (mInRequestPool) {
                        mInRequestPool.add(request);
                    }
                }
            }
        }
    }

再看如何dispatch消息的,这个就和adb协议直接相关了:

    void dispatchMessage(AdbMessage message) {
        int command = message.getCommand();
        switch (command) {  
            case AdbMessage.A_SYNC:
                log("got A_SYNC");//收到同步command
                break;
            case AdbMessage.A_CNXN:
                handleConnect(message);//收到connect response,处理下
                break;
            case AdbMessage.A_OPEN:
            case AdbMessage.A_OKAY:
                AdbSocket socket = getSocket(message.getArg1());
                if (socket == null) {
                    log("ERROR socket not found");
                } else {
                    mPeerId = message.getArg0(); //收到ok response 
                    synchronized (this) {
                        notify();
                    }
                }

                break;
            case AdbMessage.A_CLSE:
            case AdbMessage.A_WRTE:
                AdbSocket socket = getSocket(message.getArg1());
                if (socket == null) {
                    log("ERROR socket not found");
                } else {
                    //device往host write,即 host接收数据,这里的数据就是logcat的消息;  
                    mDevice.log(message.getDataString());
                    sendReady();
                }
                break;
        }
    }

最后

以上就是呆萌火为你收集整理的android usb 异步请求理解的全部内容,希望文章能够帮你解决android usb 异步请求理解所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部