您的位置:首页 > 移动开发 > Android开发

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

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

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的框架。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: