編輯:高級開發
比較重要的代碼段我們貼出,逐一分析,其他的網友可以直接預讀源碼:
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明天繼續講解。
隨著iPad2的曝光和iOS 4.3.1的發布,Google也開始升級android 3.0系統,Xoom平板電腦將收到android 3.0.1 HRI66的更新,與
android 3.0 SDK已經正式發布了,android前面幾個版本已經證明它足夠成功了,但是在Andriod的全球成功後面是手機制造商的愛與恨的關系。Andrio
2.3SDK的兩個新特點:1.剛安裝上2.3時,查看sdk目錄,發現在<SDK_PATH>\tools下新增了一文件夾“proguard”,如下圖,我就在想
由於android平台本身的優勢,引來了很多手機廠商的關注。 一大堆 android 手機發售在即,開發人員向該平台投入了巨大的資源,這可能會迎來 android程序的