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

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

staticvoidread(SocketChannelchan,byte[]data,intlength,inttimeout)

throwsTimeoutException,IOException{

ByteBufferbuf=ByteBuffer.wrap(data,0,length!=-1?length:data.length);//从字节数组中实例化ByteBuffer

intnumWaits=0;

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

intcount;

count=chan.read(buf);

if(count<0){

thrownewIOException("EOF");//读到末尾

}elseif(count==0){

if(timeout!=0&&numWaits*WAIT_TIME>timeout){

thrownewTimeoutException();

}

try{

Thread.sleep(WAIT_TIME);

}catch(InterruptedExceptionie){

}

numWaits++;

}else{

numWaits=0;

}

}

}

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

staticvoidwrite(SocketChannelchan,byte[]data,intlength,inttimeout)

throwsTimeoutException,IOException{

ByteBufferbuf=ByteBuffer.wrap(data,0,length!=-1?length:data.length);

intnumWaits=0;

while(buf.position()!=buf.limit()){

intcount;

count=chan.write(buf);//发送数据从ByteBuffer中

if(count<0){

thrownewIOException("channelEOF");

}elseif(count==0){

if(timeout!=0&&numWaits*WAIT_TIME>timeout){

thrownewTimeoutException();

}

try{

Thread.sleep(WAIT_TIME);

}catch(InterruptedExceptionie){

}

numWaits++;

}else{

numWaits=0;

}

}

}

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

staticvoidsetDevice(SocketChanneladbChan,IDevicedevice)

throwsTimeoutException,AdbCommandRejectedException,IOException{

//ifthedeviceisnot-1,thenwefirsttelladbwe'relookingtotalk

//toaspecificdevice

if(device!=null){

Stringmsg="host:transport:"+device.getSerialNumber();//最后的获取序列号,android123提示大家在adb命令中是adbget-serialno

byte[]device_query=formAdbRequest(msg);

write(adbChan,device_query);

AdbResponseresp=readAdbResponse(adbChan,false/*readDiagString*/);

if(resp.okay==false){

thrownewAdbCommandRejectedException(resp.message,

true/*errorDuringDeviceSelection*/);

}

}

}

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

publicstaticvoidreboot(Stringinto,InetSocketAddressadbSockAddr,

Devicedevice)throwsTimeoutException,AdbCommandRejectedException,IOException{

byte[]request;

if(into==null){

request=formAdbRequest("reboot:");//$NON-NLS-1$

}else{

request=formAdbRequest("reboot:"+into);//$NON-NLS-1$

}

SocketChanneladbChan=null;

try{

adbChan=SocketChannel.open(adbSockAddr);

adbChan.configureBlocking(false);

//ifthedeviceisnot-1,thenwefirsttelladbwe'relookingtotalk

//toaspecificdevice

setDevice(adbChan,device);

write(adbChan,request);

}finally{

if(adbChan!=null){

adbChan.close();

}

}

}

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

相关推荐