概述
先贴这个adbtest的例子,用android的usb sdk传输adb协议数据,将android的logcat信息打印再屏幕上。
我研究这个例子的目的是为了实现usb传输tcpip数据,需要借用adb。
http://www.java2s.com/Code/Android/Hardware/USBdevicethatsupportstheadbprotocol.htm
这例子具体有几个类:adbdevice
、adbmessage
、`adbsocket
。
其中adbdevice
是主类,里面有个线程WaitThread
主要是用到usb异步读的地方。
huesb异步操作的主要流程是:
1. 调用initialize(UsbDeviceConnection connection, UsbEndpoint endpoint)
初始化好1个request,connection是指明连接的,endpoint可以是相应的in或out;
2. 调用queue(ByteBuffer buffer, int length)
提交Buffer去读或者写数据;
3. 调用setClientData(Object data)
可以做标记,具体作用在下面代码的注释里。
4. 调用usbDeviceConection的requestWait()
等待request异步请求生效;注意requestWait()对所有endpoint提交的request都可能生效。很重要的一点是要判断提交的request是否是wait到的request,才能控制不同endpoint的数据流。
贴代码和注释:
private class WaiterThread extends Thread {
public boolean mStop;
public void run() {
// start out with a command read
AdbMessage currentCommand = new AdbMessage();
AdbMessage currentData = null;
//封装了usbRequest.setClientData和queue,请求读adb协议的command header数据段
currentCommand.readCommand(getInRequest());
while (true) {
synchronized (this) {
if (mStop) {
return;
}
}
//阻塞等待request被响应,
UsbRequest request = mDeviceConnection.requestWait();
if (request == null) {
break;
}
AdbMessage message = (AdbMessage)request.getClientData();
request.setClientData(null);
AdbMessage messageToDispatch = null;
/*
*为何要如此检查?因为requestWait()等的是所有endpoint提交的request,任何1个都有可能
*怎么检查的?在queque的时候,用setclientdata做了标记,然后再比较request的时候,用
*getclientdata的结果进行对比
*/
if (message == currentCommand) {
int dataLength = message.getDataLength();
// read data if length > 0
if (dataLength > 0) {
//请求读adb协议的command data数据段
message.readData(getInRequest(), dataLength);
currentData = message;
} else {
messageToDispatch = message;
}
currentCommand = null;
//只需关注自己提交的、而不是其他endpoint的 command data request
} else if (message == currentData) {
messageToDispatch = message;
currentData = null;
}
//command data字段 准备解析并处理
if (messageToDispatch != null) {
// queue another read first
//先提交一次read command header, 为下一次接收做准备
currentCommand = new AdbMessage();
currentCommand.readCommand(getInRequest());
// then dispatch the current message
dispatchMessage(messageToDispatch);
}
// put request back into the appropriate pool
//in or out request用完了 重新放回List中;
if (request.getEndpoint() == mEndpointOut) {
releaseOutRequest(request);
} else {
synchronized (mInRequestPool) {
mInRequestPool.add(request);
}
}
}
}
}
再看如何dispatch消息的,这个就和adb协议直接相关了:
void dispatchMessage(AdbMessage message) {
int command = message.getCommand();
switch (command) {
case AdbMessage.A_SYNC:
log("got A_SYNC");//收到同步command
break;
case AdbMessage.A_CNXN:
handleConnect(message);//收到connect response,处理下
break;
case AdbMessage.A_OPEN:
case AdbMessage.A_OKAY:
AdbSocket socket = getSocket(message.getArg1());
if (socket == null) {
log("ERROR socket not found");
} else {
mPeerId = message.getArg0(); //收到ok response
synchronized (this) {
notify();
}
}
break;
case AdbMessage.A_CLSE:
case AdbMessage.A_WRTE:
AdbSocket socket = getSocket(message.getArg1());
if (socket == null) {
log("ERROR socket not found");
} else {
//device往host write,即 host接收数据,这里的数据就是logcat的消息;
mDevice.log(message.getDataString());
sendReady();
}
break;
}
}
最后
以上就是呆萌火为你收集整理的android usb 异步请求理解的全部内容,希望文章能够帮你解决android usb 异步请求理解所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复