说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

Android开发进阶之NIO非阻塞包(六)

HTML文档下载 WORD文档下载 PDF文档下载
Android开发进阶之NIO非阻塞包(六)

作者:Android开发网


  有关Android NIO的相关内容,本次Android123整理并归类如下,为了让大家感觉NIO和Android平台联系的紧密,这里我们结合ADT插件的重要开发工具DDMS中的源码进行分析。在android git中的sdk.git文件中,可以找到ddmlib这个文件夹。有关PC和手机的互通内核在这里使用了Java来完全实现。这里Android开发网一起帮助大家了解下PC同步软件的开发原理同时学习下Java中的New I/O技术。

   比较重要的代码段我们贴出,逐一分析,其他的网友可以直接预读源码:

   AdbHelper.java文件中

   public static SocketChannel open(InetSocketAddress adbSockAddr,
            Device device, int devicePort) //这是一个重载版本,主要是关联Device实例。
            throws IOException, TimeoutException, AdbCommandRejectedException {

        SocketChannel adbChan = SocketChannel.open(adbSockAddr); //构造SocketChannel对象,使用常规的open方法创建
        try {
            adbChan.socket().setTcpNoDelay(true); //设置TCP非延迟
            adbChan.configureBlocking(false); //非阻塞

            setDevice(adbChan, device); //本句和NIO没有多大关系,这句是指定具体的设备,比如模拟器,或Android手机的厂家代号,比如宏达电的以HTXXXXX这样的方式

            byte[] req = createAdbForwardRequest(null, devicePort); //设置端口转发,这句很关键,否则PC和手机通过USB是无法互通的。
            write(adbChan, req); //发送数据

            AdbResponse resp = readAdbResponse(adbChan, false); //读取收到的内容
            if (resp.okay == false) {
                throw new AdbCommandRejectedException(resp.message);
            }

            adbChan.configureBlocking(true);
        } catch (TimeoutException e) { //一般要处理超时异常
            adbChan.close(); //释放channel句柄
            throw e;
        } catch (IOException e) { //处理常规的IO异常
            adbChan.close();
            throw e;
        }

        return adbChan;
    }

   有关读取ADB返回的报文方法

  static AdbResponse readAdbResponse(SocketChannel chan, boolean readDiagString)
            throws TimeoutException, IOException {

        AdbResponse resp = new AdbResponse();

        byte[] reply = new byte[4]; //创建4字节数组,主要检测成功与否,adb的协议是成功返回 okay,失败fail,等等。
        read(chan, reply); //读取具体的返回

        if (isOkay(reply)) { //判断是否成功
            resp.okay = true;
        } else {
            readDiagString = true; // look for a reason after the FAIL
            resp.okay = false;
        }

        // not a loop -- use "while" so we can use "break"
        try {
            while (readDiagString) {
                // length string is in next 4 bytes
                byte[] lenBuf = new byte[4];
                read(chan, lenBuf); //读取一个字节数组,最终为了转为一个整形

                String lenStr = replyToString(lenBuf); //字节数组转为String

                int len;
                try {
                    len = Integer.parseInt(lenStr, 16); //String转为整形,这里Android123提示,这种写法可能比较愚蠢,但是下面为Log输出提供了一点点的便利。
                } catch (NumberFormatException nfe) {
                    Log.w("ddms", "Expected digits, got '" + lenStr + "': "
                            + lenBuf[0] + " " + lenBuf[1] + " " + lenBuf[2] + " "
                            + lenBuf[3]);
                    Log.w("ddms", "reply was " + replyToString(reply));
                    break;
                }

                byte[] msg = new byte[len];
                read(chan, msg);

                resp.message = replyToString(msg);
                Log.v("ddms", "Got reply '" + replyToString(reply) + "', diag='"
                        + resp.message + "'");

                break;
            }
        } catch (Exception e) {
            // ignore those, since it's just reading the diagnose string, the response will
            // contain okay==false anyway.
        }

        return resp;
    }

   有关PC上对Android手机屏幕截图的方法之一:

   static RawImage getFrameBuffer(InetSocketAddress adbSockAddr, Device device)
            throws TimeoutException, AdbCommandRejectedException, IOException {

        RawImage imageParams = new RawImage();
        byte[] request = formAdbRequest("framebuffer:"); // 读取手机端adbd服务器的framebuffer调用返回的数组

        byte[] nudge = {
            0
        };
        byte[] reply;

        SocketChannel adbChan = null;
        try {
            adbChan = SocketChannel.open(adbSockAddr);
            adbChan.configureBlocking(false); //非阻塞

            setDevice(adbChan, device); //设置我们关系的设备

            write(adbChan, request); //发送framebuffer这个请求了

            AdbResponse resp = readAdbResponse(adbChan, false /* readDiagString */);
            if (resp.okay == false) {   //判断返回是否ok。
                throw new AdbCommandRejectedException(resp.message);
            }

            reply = new byte[4];
            read(adbChan, reply); //首先返回的是一个协议,目前分为两个版本,主要是兼容模式和标准的模式,兼容模式比较少见,在2.0以后几乎看不到了。部分早期的1.6或更老的T-Mobile G1会使用兼容模式,模式不同,输出的截图中的颜色编码方式略有不同。

            ByteBuffer buf = ByteBuffer.wrap(reply);
            buf.order(ByteOrder.LITTLE_ENDIAN); //小头字节顺序

            int version = buf.getInt(); //ByteBuffer直接转int的方法,比较方便不用自己从字节数组中构造,按位计算

            int headerSize = RawImage.getHeaderSize(version); //根据返回的adb截图协议版本判断将收到的字节大小

            reply = new byte[headerSize * 4]; //分配空间,具体大小需要看协议版本
            read(adbChan, reply);

            buf = ByteBuffer.wrap(reply); //从reply数组实例化ByteBuffer
            buf.order(ByteOrder.LITTLE_ENDIAN); //注意字节序列,毕竟远端的adbd是工作在linux系统的手机上。

            if (imageParams.readHeader(version, buf) == false) { //判断是否有效,兼容这种截图协议。
                Log.e("Screenshot", "Unsupported protocol: " + version);
                return null;
            }

            Log.d("ddms", "image params: bpp=" + imageParams.bpp + ", size="
                    + imageParams.size + ", width=" + imageParams.width
                    + ", height=" + imageParams.height); //打印下截图的基本信息,比如bpp代表色深,size是需要分配dib图像的字节数组。比较原始,

            write(adbChan, nudge); //发送一个字节,代表准备接收字节数组了

            reply = new byte[imageParams.size]; //分配和图像大小一样的字节数组
            read(adbChan, reply); //接收图像字节数组,这里Android开发网提示大家对于Android 1.x可能为RGB565,分配大小为 wxhx2xsize ,而2.x以后基本上为32位的RGB8888,分配大小为wxhx4xsize

            imageParams.data = reply;
        } finally {
            if (adbChan != null) {
                adbChan.close();
            }
        }

        return imageParams;
    }

  有关Android平台PC通过USB的ADB方式和手机同步原理和NIO相关技术,Android123明天继续讲解。

励志:12位早起的IT大佬们让小伙伴们都惊呆了 独家:苹果5周年限免神作,BADLAND开发者访谈 10亿次订阅!苹果Podcast的里程碑 免费利器Unity 4.2正式发布 支持WP8、Win8和BB10 SDCC 2013:Pinterest首位中国籍工程师两场演讲议题确定 甲骨文公布中国首届“Duke选择奖”名单 Moco、X幻想、开源中国获奖 直接拿来用,10个PHP代码片段 编程的未来 数据将成为主角 OpenCL 2.0发布,带来更强悍的异构计算能力 代码审查方式大调查 辅助工具居首(信息图) 一网打尽当下NoSQL类型、适用场景及使用公司 初创公司Treasure Data:每天处理7000亿行数据的20万次查询 豌豆荚王俊煜:将推支付SDK 与开发者3:7分成 英特尔-百度移动应用测试中心(MTC)正式启动 Intel将在2014年为数据中心用户定制低功耗SoC芯片 情绪低落?没事,让计算机来帮你! 水果生意难做 前新浪架构师徐佳转行试水挖煤 思考软件开发中的快与慢 Apache CouchDB注入新鲜血液,整合分布式技术 CSS Shapes:Web设计人员的新工具 Android 4.3正式发布:四大新功能一览 史玉柱的创业经验谈 3G门户和GO桌面:海外推广的生意经 系统级编程语言性能大PK D语言成首选 解读Facebook第二季度财报 移动业务风生水起 如何避免失败,像Google一样玩转大数据 首届游戏运营技术论坛隆重开幕,共论大数据时代的游戏运营之道 OpenStack Swift遇到了Erasure Code 微软Win7 IE11开发者预览版发布 开始改进开发工具讨好开发者 个性化推荐服务商百分点宣布B轮融资1000万美金 全球著名互联网企业背后的开源力量 兄弟们~把你们的网站那出来比一比~ 兄弟们~把你们的网站那出来比一比~我的是: 注意--***~~~…………Socks2HTTP 的使用方法 怀念MM_mimi。听说mimi很少时间上网了,唉,真不好玩,看来我也要戒网了。 关于透明色 请问delphi的立方和开立方应该用什么函数? 如何让一个form处理几个submit? 紧急求救!如何判断单行编辑框输入内容是否为数字,不是给出提示,具体怎么写,谢谢!!! 收购C、C++、JAVA版的完整工程源程序 一个关于编译的问题??? 收购C、C++、JAVA版完整工程源序 VC中如何实现等待5微秒? 关于如何用代码描述rc文件, 那位用过触摸屏的,给个建议, 请问微秒级的延迟在C语言中如何实现? 请问为什么在COM中总是使用双重值针,即指针的指针? 用过,销售,触摸屏的兄弟姐妹给个建议 关于C里面的setjmp()和longjmp()函数的使用。 一个用VB偏的“图片批量转换软件”!带源代码!!! 多伦多穷人欢庆申奥失败 有人注意到了吗???directX的资源释放不干净! 谁能帮我做一个小型帐务管理(用C)??? 用delphi编程,用什么触摸屏比较好啊? 怎样在程序运行时增加子菜单(要增加的数目是未知的) 关于Sprite动画 出售代码 ACCESS的FORMS DLL调用函数问题 VB在ACCESS中应用的一个小问题! ACCESS中的FORMS问题? 再普通不过的一个问题 delphi6中还有BDE和ADO吗?它们被淘汰了吗?现在还有必要用它们来学数据库的开发吗? 50分答谢!!!---这个css定义为什么会出现这样的效果??? 各位:怎么判断表里某个字段是否存在? 纯技术问题:精通“书签“与“层“的大虾请进!!!! 一个奇怪的现象,请教高手这是怎么回事? 哪里有破解清华五行卫士密码的软件? vc++7.0好用吗? 吃完晚饭了... 可不可以让 CppWebBrowser1的背景不是白色? 热热热!!!热疯了!!! 我的喇叭哪儿去了? 我的PB程序出了问题了!!! sql server中哪个函数是用于字符串与整型之间转换的? 我想限定文本输入框只能输入10个汉字或20个英文字符,但文件输入框却只能输入10个英文字符,如何解决? 当我将这样的字符串“dsdsdsdfsdffsdsdfsdfsfdsdfsdfsfsfdsdffs.....”放入我的表格中时,无论怎样设置也不折行,影响了部局,如何解决? MFC中视图(view)是怎样随着主窗口的大小改变而改变的。 急!请教!!猫猫连接,用数据管道同时访问两库,访问不到对方的网络库(sybase) 关于电影下载 我已经把一个exe文件加入到我自己的程序中了,请问在我的程序中应该样调用该exe文件呢? 哪位高手知道RTF格式的含义?或者更好,知道Rxlib中的RXRICHEDIT控件中识别RTF格式的方法? 1、5、6合数是?质数是?2的倍数是?3的倍数是?5的倍数是?3和5的倍数是? 24和18的公因数有( ) 两个数的公因数实际也是最大公因数的( ) 85和68的最小公因数是? 7的倍数都是合数.对还是错? 54和72公因数有几个? 13和19的公因数有哪些?急. 一个数是5的倍数,它一定是合数. 16的因数:20的因数:28的因数:16和20的公因数:20和28的公因数: 13和17有没有公因数? 最小的合数的7倍:().是2.3.和5的倍数:() 15和24的公因数有哪些 2,17,13的公因数 最小的质数是最小合数的百分之几 3的所有倍数都是合数.对还是错 24和9的最小公因数是几? 最小的质数和最小的合数的积是几 3的倍数中,除了(),其他的数都是合数 24和144的最小公因数是什么?顺便20和8的最小公倍数、 750和625的最小公因数 、30和18的最小公因数 最小的合数比最小的质数多( )% 3的倍数是合数,这个对么? 42和54的最大因数 最小质数是什么?最小合数是什么? 3.23的倍数一定是合数 15与20最大公因数是什么? 最小的合数是最小的质数的( )五年级轻松十五分上的 1,0,2,4,5,10,17,36,47,48,53,76,93哪些是素数哪些是合数 8和12的最大公因数是( ),最小公因数是( ). 最小的合数比最小的质数多百分之几 在1、2、27、33、47、53、68、84中,既是奇数又是合数的有();既是偶数又是质数的有();既是合数又是在1、2、27、33、47、53、68、84中,既是奇数又是合数的有();既是偶数又是质数的有 8和24的公因数共有多少个?在15和18的公倍数中,那一个最接近250?求20和32的最大公因数?68x36是34x9的多少倍? 还有方法,急求P的所有因数是1,2,4,8,16.如果P和Q的最小公倍数是80,下列那一个数不可能 最小的合数,比最小的质数多百分之几? 0.1 2 0.5 9分之2 15 奇数有 偶数 质数 合数 整数 15和16最小的公倍数是多少? 最大的合数和最小的质数是多少? 在1.2,0,4,30,17,15,1,18中整数有(),偶数有(),奇数有(),合数有(),质数有(). 32和45的公因数 最小的质数与最小的合数的最大公因数是几 在1--20的自然数中,质数有(),其中()是偶数 8是32和48的() a.因数b.最大因数c.公因数 100以内最大的质数与最小的合数的和是几,差是几? 20既是偶数又是质数的有? 32和24怎么求最大的公因数 7的所有倍数都是合数 20以内既是奇数又是合数的数有()不要小数!既是偶数又是质数的数有?在自然数中1——20中奇数有()偶数有()质数有()合数有() 32和6的公因数 2的倍数都是合数吗?不是质数? 在20以内的自然数中,既是奇数有是合数的有(),既是偶数又是质数的数有(),既是奇数又不是质数的数是( 40和45的公因数:( ) 五的倍数都是合数吗? 在小于20的自然数中,不是奇数的质数有( ),是偶数的合数有( 40和48的最小公因数 9的倍数都是合数吗自然数中,凡是9的倍数()A都是质数 B都是奇书 C都是3的倍数 D都是偶数 20以内的偶数和质数麻烦列举出来 17和8的最小公因数 6的倍数一定是合数对还是错 24和18的最大的公因数是( ),最小的倍是(24和18的最大的公因数是( ),最小的倍是( ) 17,29,13,19的最小公因数是多少 6的倍数肯定是合数,这句话对吗 24和20的公因数有哪些 14和35的最小公因数 19和8的最小公因数
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn