有关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明天继续讲解。
相关推荐
### Android开发进阶之NIO非阻塞包 #### NIO非阻塞通讯方式解析 在探讨Android DDMS源码中的NIO(Non-blocking I/O)非阻塞通讯方式时,我们首先需要理解NIO的基本概念及其在Android开发中的应用。 **NIO简介**:...
### Android开发进阶之NIO非阻塞包 #### 关键知识点概述 1. **NIO(New I/O)的概念**:NIO是Java 1.4版本开始引入的新I/O处理模型,它通过非阻塞的方式提高了I/O操作的性能。在Android开发中,利用NIO可以显著...
总的来说,Android开发中的NIO技术提供了高性能、非阻塞的网络通信解决方案,有效地解决了多线程管理和资源消耗的问题。它不仅简化了并发编程,也提升了Android应用程序在网络通信方面的效率。对于Android开发者来说...
8. **Java NIO**:非阻塞I/O操作在Java中的实现与应用。 9. **Java Web基础**:涵盖前端脚本语言、框架等基础知识。 10. **JavaScript DOM视频**:了解网页元素的操作与控制。 11. **jQuery视频**:简化HTML文档遍历...
Java的IO系统分为传统IO和NIO(非阻塞IO)。RandomAccessFile允许随机访问文件,而NIO引入了通道和缓冲区,提高了数据传输效率。异常处理是程序健壮性的关键,Java的异常分为检查异常和运行时异常,理解异常的层次...
I/O流处理和NIO(非阻塞I/O)对于读写文件和网络通信至关重要。线程与并发编程是Java的强项,涉及线程同步、死锁避免、并发工具类(如Semaphore、CountDownLatch)等内容。 再者,Java EE(企业版)是Java在服务器...
5. **IO/NIO**:Java的I/O系统升级到NIO(非阻塞I/O),Channel、Buffer和Selector的使用。 6. **网络编程**:Socket编程,实现客户端和服务端的通信。 7. **枚举与注解**:枚举类型的使用,注解的定义和应用,以及...
对于IO流,理解输入输出处理,文件操作,以及NIO(非阻塞I/O)的概念也是必要的。 进一步,深入研究Java的反射机制,它允许我们在运行时动态地获取类的信息并调用其方法。还要学习Java的泛型,它提供了类型安全的...
- **网络I/O**:阻塞I/O、非阻塞I/O、NIO(New I/O)等。 - **JVM内存管理**: - **堆和栈**:理解它们的区别及其在程序中的作用。 - **垃圾回收**:GC算法、堆内存分区(如Young区、Old区)等。 - **性能调优*...
3. NIO(New Input/Output):提供非阻塞I/O,适用于高性能网络通信,如SocketChannel、Selector和Buffer。 六、网络编程 1. Socket编程:通过ServerSocket和Socket实现客户端-服务器通信,理解TCP和UDP协议的区别...
- **IO流与NIO**:文件操作,网络通信,以及非阻塞I/O模型。 - **多线程**:线程同步、死锁避免以及并发工具类的使用。 - **集合框架**:ArrayList、LinkedList、HashMap等数据结构的使用和实现原理。 - **反射...
学习者还需要熟悉集合框架,如ArrayList、LinkedList、HashMap等,以及IO流和NIO(非阻塞I/O)系统,这些用于数据的输入输出和文件操作。 在高级主题中,线程和并发处理是Java的一大亮点,理解如何创建和管理线程,...
7. **IO与NIO**:包括旧的I/O模型和新的非阻塞I/O模型,有助于优化读写操作。 8. **Java Swing和JavaFX**:介绍图形用户界面的构建,用于开发桌面应用。 9. **JDBC**:讲解如何连接数据库,执行SQL语句,处理结果...
3. **I/O流**:`java.io`包提供了丰富的流处理类,通过源码我们可以学习如何进行数据的读写,了解缓冲流、字符流与字节流的区别,以及NIO(非阻塞I/O)的实现。 4. **集合框架**:Java集合框架是数据结构和算法的...
* Java 高级知识:Annotation、IO 和 NIO、AIO、多线程、线程池、阻塞、非阻塞、异步网络通信、反射、动态代理 二、JDBC 编程 * SQL 基础:基础 SQL 语句、基本查询、多表查询、子查询、结果集的交、并、差运算 * ...
5. **IO流与NIO**:第六章可能涵盖输入输出流(IO)和非阻塞I/O(NIO)的概念,学习者将学会如何读写文件,网络通信,以及高效处理数据流。 6. **多线程编程**:第七章将讲解并发编程,包括线程的创建、同步机制...
- **NIO.2**:增加了文件系统操作的API,增强了非阻塞I/O能力。 - **Scripting API**:允许在Java应用程序中嵌入和使用脚本语言,如JavaScript。 - **Java Database Connectivity (JDBC) 4.0**:改进了数据库连接...
进阶课程包括JUC并发编程、NIO非阻塞I/O等,帮助开发者提升性能优化能力。 JavaWeb阶段,尚硅谷提供JavaScript DOM编程、jQuery、Ajax等前端技术教程,以及JavaWeb核心技术和企业级项目实战,如Servlet、JSP、MVC...