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

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明天继续讲解。

“化云为雨”一小滴:北京,3G手机+蓝牙打印机实现智能抄表 金山云与蓝汛联合提供云基础设施服务 MongoDB出新招,增加对Hive的支持 编程语言收入榜 Java排第三 直接拿来用!10段超有用的Git命令行代码 Google Cast SDK正式版发布:自动适配,修复Bug 频受红杉资本青睐,商业智能初创公司Birst靠的是什么? 2013百度世界大会要点精华回顾 WebApp开发框架Clouda、轻应用... 对新手有用的JavaScript开发小建议 磨剑三载,且看从容应对14.3万TPS的Twitter是怎样炼成的! 兰亭集势:被高估的“长尾式采购” 谁说WP手机不行?微软称已成拉丁美洲第二大移动平台 Windows 8之父Steven Sinofsky加盟风投机构A16Z SDCC 2013演讲议题抢先看 腾讯、阿里、支付宝、网易…… [开源推荐]Google开源基于Deep Learning的word2vec工具 【开源专访】DWZ团队:致力打造最简单的Web前端开发方式 Linux黑客车库创业:服务器操作系统CoreOS颠覆互联网 时间序列数据处理的角逐:MongoDB vs. Cassandra 移动周报:Sphinx游戏引擎的前世今生 联想K900评测:英特尔X86兼容性明显提升(组图) 小米手机-HAXLR8on硬件黑客马拉松:32小时的创客狂欢 鲍尔默宣布下台后,微软应该做好这几件事情 IGT张奇伟:从空间物理到博彩游戏研发 Bing即将推出新功能 用户可直接在搜索结果页购买商品 【开源专访】郑晔谈Moco框架的前世今生以及Java编程之道 CTO俱乐部第108期下午茶:电商在微信上的现状与未来 SDCC 2013讲师议题确定 门票即将售罄(图) 简化工作流程,10款必备的HTML5开发工具 六大领域考评鲍尔默微软掌舵能力,只一“C”尔? 剥离自雅虎的Hortonworks:低调发展,三年融资近1亿美元 Google的中国梦如何死于傲慢与不得力公关 菜鸟的问题 怎么web页面控制打印范围? 推箱子的每一关是用算法算的,还是人编的? 为什么北京的高程准考证到现在还没有发呀??? 谁有类似万网的域名查询系统??高分相送! 我想搞软件开发,学点网络知识,请问有多大用处? 在ASP.Net中,用VB.net写代码,怎么取得到的记录集中的记录个数啊? 请教双网隔离方案 重装系统以后,如何对Microsoft Outlook里的各种参数、选项进行设置? 求OA设计方案 请 ychuiming(飞天),hkbarton(宁静至远||淡泊明志) 进来接分 在ASP.Net中,用VB.net写代码,怎么取得到的记录集中的记录个数啊? pb中有没有与或操作符?就象VB中的Xor这类操作符? 如何从一个单一的JSP程序员迈进J2EE的世界--请高手指点迷津 第一次来csdn,请各位多多关照。随便问一个巨傻的关于BDE的问题。 离职,却被原来公司经理阴了一下 求AutoResize控件(分不够可加) 谁做过远程代理的程序(急,100分求助,不够再给) mm不让我去接她 树形菜单的问题 如何限制对SQLSERVER的请求访问数? 各位,跪谢了!不能见死不救啊! session 问题 我的服务器 无法更改 session值了 有没有好的远程服务器监控软件 主细表类型的报表问题,希望有人帮我!先谢谢了!(急) 大家救救我得机子吧~~ 极度深奥的问题!!有没有谁知道“xp_logattach ”这个存储过程的实际作用与用法。 ADO 错误代码 (能否置顶啊..斑主) ini文件的保存 智能卡读写设备(成熟技术)== 想借鉴请进 提问?关于用DreamweaverMX处理网页参数问题? ping命令的奇怪问题,你遇到过没? 有谁知道windows一共出了多少版本(包括不同语言,不同版本) 有谁知道windows一共出了多少版本(包括不同语言,不同版本) 初学者,请教小问题~~~ 用opengl写的一个屏保,有些问题想和大家讨论 帮我看看 有谁知道windows一共出了多少版本(包括不同语言,不同版本) 想暴力解决点问题,大家给点意见! 熟悉J2EE和Web,但是英语四级没过,郁闷呀!散分讨论 怎样使用一个窗体总是显示在最后面和怎样在windows桌面上写上文字。 如果全世界只有一个男人... .net组件有没有对象池的功能? 编程男友和淘气女友!绝配!!!! 企业管理器很慢? 关于窗体的问题 我明年打算考中程,到底难吗? 网络编程 为什么我的mdb数据库不能设置对象指针可以移动啊? 急啊!!!有没有做过论坛发帖机啊能否帮我一下就是怎样提交CSDN论坛的注册信息然后得到左边的树列表和右边的列表 本人做系统时有一个操作员列表,为使每个操作员的密码保密,想在数据表据中将密码用*号代替,怎么办? 为什么说法国封建法是西欧中世纪法的典范 Everyone's stretched thin.We're not even sure how the Crucible works. please add_“s”after_“r”.-OK,i understand. A an an Ba an C an the Dthe the 用什么方法在空气中取水,量需要大一些的 送友人 理解浮云和落日 快加油 齐桓公以霸的“以” Jim has two sister.对two提问 他正在吃晚饭的英文怎么写 How to say"海洋已死,世界已死"in English?Can you add "both" to the sentence? how to emplove english online may i have an icecream sandwish,please,please?怎么两个please? 印度开建“全球最高”塑像印度开建“全球最高”塑像 呼吁民众捐斯诺登找到工作 在俄社交网站上班英国检方称《世界新闻报》曾窃听哈里王“歧视胖子” 香奈儿艺术总监惹官司戴“谷歌眼镜”开车遭传讯偷渡客残杀5人 凸显底层华人困境普京登顶权势榜 只怪奥巴马不争气首个完整境外诈骗集团被批捕新一轮伊核对话可能取得重要进展奥巴马豪华座驾“野兽”细节曝光 具备春节期间爆竹炸伤患者骤增 部分患者失“人日游草堂”祭祀活动举行 留学生吟韩上路环保车超18万 将加强环保汽车古巴:在美国误运导弹事件中 双方进行奥斯卡宣布更改会员资格 新制度遭多方甘肃甘南藏乡村落闹新春:吃百家饭 转又到情人节 动物爱侣摆爱心“虐狗”(两男子来津“出差” “水果生意”掩盖网传河南18地市酒量排行榜 郑州人战女童被拐六年 民警助其父女重聚郑州“禁炮”空气成绩单:4年来最“清仙途异界之召唤水浒108将终极军刀千金非千金医典天术华夏军团异界行重生之唯吾天下寒号鸟魔唤巫师重生之叱咤风云登州路啤酒街旅游长白瀑布群旅游地王观光旅游水上茶乡九鹏溪旅游成都锦江川剧院旅游仙人崖旅游唐城墙遗址公园旅游古堰画乡旅游关山旅游太素宫旅游埃舍尔博物馆旅游
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘