zoukankan      html  css  js  c++  java
  • Android开发进阶之NIO非阻塞包(七)

    今天我们继续就Android DDMS源码一起分析NIO非阻塞通讯方式,Android123也会给大家分享下手机和PC互通中的一些技术。在NIO中有关SocketChannelByteBuffer的使用细节,可以在今天文章中

       static void read(SocketChannel chan, byte[] data, int length, int timeout)
                throws TimeoutException, IOException {
            ByteBuffer buf = ByteBuffer.wrap(data, 0, length != -1 ? length : data.length); //
    从字节数组中实例化ByteBuffer
            int numWaits = 0;

            while (buf.position() != buf.limit()) {  //循环接收数据
                int count;

                count = chan.read(buf);
                if (count < 0) {
                        throw new IOException("EOF"); //
    读到末尾
                } else if (count == 0) {
                    if (timeout != 0 && numWaits * WAIT_TIME > timeout) {
                        throw new TimeoutException();
                    }
                     try {
                        Thread.sleep(WAIT_TIME);
                    } catch (InterruptedException ie) {
                    }
                    numWaits++;
                } else {
                    numWaits = 0;
                }
            }
        }

        有关SocketChannel的写操作,就是发送数据代码如下:

      static void write(SocketChannel chan, byte[] data, int length, int timeout)
                throws TimeoutException, IOException {
            ByteBuffer buf = ByteBuffer.wrap(data, 0, length != -1 ? length : data.length);
            int numWaits = 0;

            while (buf.position() != buf.limit()) {
                int count;

                count = chan.write(buf); //发送数据从ByteBuffer
                if (count < 0) {
                           throw new IOException("channel EOF");
                } else if (count == 0) {
                                 if (timeout != 0 && numWaits * WAIT_TIME > timeout) {
                                throw new TimeoutException();
                    }
                     try {
                        Thread.sleep(WAIT_TIME);
                    } catch (InterruptedException ie) {
                    }
                    numWaits++;
                } else {
                    numWaits = 0;
                }
            }
        }

       有关ADB如何选择一个具体的设备,可以使用 setDevice 方法,这样当电脑中有模拟器或链接了多个手机,可以通过设备序列号,选择需要通讯的设备。

      static void setDevice(SocketChannel adbChan, IDevice device)
                throws TimeoutException, AdbCommandRejectedException, IOException {
            // if the device is not -1, then we first tell adb we're looking to talk
            // to a specific device
            if (device != null) {
                String msg = "host:transport:" + device.getSerialNumber(); //
    最后的获取序列号,android123提示大家在adb命令中是adb get-serialno

                byte[] device_query = formAdbRequest(msg);

                write(adbChan, device_query);

                AdbResponse resp = readAdbResponse(adbChan, false /* readDiagString */);
                if (resp.okay == false) {
                    throw new AdbCommandRejectedException(resp.message,
                            true/*errorDuringDeviceSelection*/);
                }
            }
        }

        通过PC控制手机重启的代码,当然这里需要Root权限才能执行

       public static void reboot(String into, InetSocketAddress adbSockAddr,
                Device device) throws TimeoutException, AdbCommandRejectedException, IOException {
            byte[] request;
            if (into == null) {
                request = formAdbRequest("reboot:"); //$NON-NLS-1$
            } else {
                request = formAdbRequest("reboot:" + into); //$NON-NLS-1$
            }

            SocketChannel adbChan = null;
            try {
                adbChan = SocketChannel.open(adbSockAddr);
                adbChan.configureBlocking(false);

                // if the device is not -1, then we first tell adb we're looking to talk
                // to a specific device
                setDevice(adbChan, device);

                write(adbChan, request);
            } finally {
                if (adbChan != null) {
                    adbChan.close();
                }
            }
        }

      我们可以看到基本上,每个命令的执行,都是用了单独SocketChannel通过非阻塞方式执行,这样大大加强了并发,所以DDMS可以一边处理Logcat打印,显示堆信息,处理文件管理等等,有关NIO服务器的内容,Android开发网将着重分析MonitorThread.java这个文件,一起说下NIO的框架。

     

  • 相关阅读:
    eclipse+myeclipse 使用技巧备忘
    程序员的自我修养
    枚举工具类 EnumUtils
    日期/时间处理工具 DateTimeUtil
    轻松了解Spring中的控制反转和依赖注入(一)
    了解SpringMVC框架及基本工作流程
    HTTP请求行、请求头、请求体详解
    Tomcat项目部署问题记录
    入手IntelliJ IDEA 常用配置
    解决阿里云OSS跨域问题
  • 原文地址:https://www.cnblogs.com/cpcpc/p/2123003.html
Copyright © 2011-2022 走看看