是什么导致 UsbRequest 从队列方法中抛出 IO 异常?
What causes UsbRequest to throw IO Exception from queue method?
我正在尝试使用 Mike Wakerly 的 usb-serial-for-android 库通过 USB 串口与 Arduino Mega 克隆进行通信(谢谢!)我已经解决了权限错误,但是现在我遇到了以下问题:
09-02 15:08:03.628 18694-18792/org.drivebuv.buvmonitor W/SerialInputOutputManager﹕ Run ending due to exception: Error queueing request.
java.io.IOException: Error queueing request.
at org.drivebuv.buvmonitor.CdcAcmSerialDriver$CdcAcmSerialPort.read(CdcAcmSerialDriver.java:168)
at org.drivebuv.buvmonitor.SerialInputOutputManager.step(SerialInputOutputManager.java:158)
at org.drivebuv.buvmonitor.SerialInputOutputManager.run(SerialInputOutputManager.java:140)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
方法如下。抛出错误的行是带有 !request.queue(buf, dest.length)
的 if 循环
public int read(byte[] dest, int timeoutMillis) throws IOException {
if (mEnableAsyncReads) {
final UsbRequest request = new UsbRequest();
try {
request.initialize(mConnection, mReadEndpoint);
final ByteBuffer buf = ByteBuffer.wrap(dest);
if (!request.queue(buf, dest.length)) {
throw new IOException("Error queueing request.");
}
final UsbRequest response = mConnection.requestWait();
if (response == null) {
throw new IOException("Null response");
}
final int nread = buf.position();
if (nread > 0) {
Log.d(TAG, HexDump.dumpHexString(dest, 0, Math.min(32, dest.length)));
return nread;
} else {
return 0;
}
} finally {
request.close();
}
}
final int numBytesRead;
synchronized (mReadBufferLock) {
int readAmt = Math.min(dest.length, mReadBuffer.length);
numBytesRead = mConnection.bulkTransfer(mReadEndpoint, mReadBuffer, readAmt,
timeoutMillis);
if (numBytesRead < 0) {
// This sucks: we get -1 on timeout, not 0 as preferred.
// We *should* use UsbRequest, except it has a bug/api oversight
// where there is no way to determine the number of bytes read
// in response :\ -- http://b.android.com/28023
if (timeoutMillis == Integer.MAX_VALUE) {
// Hack: Special case "~infinite timeout" as an error.
return -1;
}
return 0;
}
System.arraycopy(mReadBuffer, 0, dest, 0, numBytesRead);
}
return numBytesRead;
}
之前,他的 CdcAcmSerialDriver.java 第 319 行似乎有一个错误:
mDataInterface = mDevice.getInterface(1);
所以我将 1 更改为 0,这修复了基于 的索引越界错误。最后将他所有的 .java 文件移动到我的包中以便对其进行编辑。甚至不确定这是否相关。
目前,我的应用程序在发生该异常后挂起。底线:我在低级代码中游来游去,运行 出局了。你能给我指点陆地吗:)?
所以在包括 Chromium 在内的所有代码示例中,none 实际上检查了 request.queue 的结果。看这里http://src.chromium.org/chrome/trunk/src/media/base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java
if (!request.queue(buf, dest.length)) {
throw new IOException("Error queueing request.");
}
所以在代码内部,只要有异常,SerialInputOutputManager 就会停止,所以最好的办法是在出错时重新运行它。
@Override
public void onRunError(Exception e) {
Log.d(TAG, "Runner stopped.");
//restart if the error is the queue
}
或者将其修改为不 运行 异常,但是 requestWait 很可能 return 为空。
如果我想出一个天才的解决方案,它会在我的 github 项目中使用相同的库。
我正在尝试使用 Mike Wakerly 的 usb-serial-for-android 库通过 USB 串口与 Arduino Mega 克隆进行通信(谢谢!)我已经解决了权限错误,但是现在我遇到了以下问题:
09-02 15:08:03.628 18694-18792/org.drivebuv.buvmonitor W/SerialInputOutputManager﹕ Run ending due to exception: Error queueing request.
java.io.IOException: Error queueing request.
at org.drivebuv.buvmonitor.CdcAcmSerialDriver$CdcAcmSerialPort.read(CdcAcmSerialDriver.java:168)
at org.drivebuv.buvmonitor.SerialInputOutputManager.step(SerialInputOutputManager.java:158)
at org.drivebuv.buvmonitor.SerialInputOutputManager.run(SerialInputOutputManager.java:140)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
方法如下。抛出错误的行是带有 !request.queue(buf, dest.length)
public int read(byte[] dest, int timeoutMillis) throws IOException {
if (mEnableAsyncReads) {
final UsbRequest request = new UsbRequest();
try {
request.initialize(mConnection, mReadEndpoint);
final ByteBuffer buf = ByteBuffer.wrap(dest);
if (!request.queue(buf, dest.length)) {
throw new IOException("Error queueing request.");
}
final UsbRequest response = mConnection.requestWait();
if (response == null) {
throw new IOException("Null response");
}
final int nread = buf.position();
if (nread > 0) {
Log.d(TAG, HexDump.dumpHexString(dest, 0, Math.min(32, dest.length)));
return nread;
} else {
return 0;
}
} finally {
request.close();
}
}
final int numBytesRead;
synchronized (mReadBufferLock) {
int readAmt = Math.min(dest.length, mReadBuffer.length);
numBytesRead = mConnection.bulkTransfer(mReadEndpoint, mReadBuffer, readAmt,
timeoutMillis);
if (numBytesRead < 0) {
// This sucks: we get -1 on timeout, not 0 as preferred.
// We *should* use UsbRequest, except it has a bug/api oversight
// where there is no way to determine the number of bytes read
// in response :\ -- http://b.android.com/28023
if (timeoutMillis == Integer.MAX_VALUE) {
// Hack: Special case "~infinite timeout" as an error.
return -1;
}
return 0;
}
System.arraycopy(mReadBuffer, 0, dest, 0, numBytesRead);
}
return numBytesRead;
}
之前,他的 CdcAcmSerialDriver.java 第 319 行似乎有一个错误:
mDataInterface = mDevice.getInterface(1);
所以我将 1 更改为 0,这修复了基于
目前,我的应用程序在发生该异常后挂起。底线:我在低级代码中游来游去,运行 出局了。你能给我指点陆地吗:)?
所以在包括 Chromium 在内的所有代码示例中,none 实际上检查了 request.queue 的结果。看这里http://src.chromium.org/chrome/trunk/src/media/base/android/java/src/org/chromium/media/UsbMidiDeviceAndroid.java
if (!request.queue(buf, dest.length)) {
throw new IOException("Error queueing request.");
}
所以在代码内部,只要有异常,SerialInputOutputManager 就会停止,所以最好的办法是在出错时重新运行它。
@Override
public void onRunError(Exception e) {
Log.d(TAG, "Runner stopped.");
//restart if the error is the queue
}
或者将其修改为不 运行 异常,但是 requestWait 很可能 return 为空。
如果我想出一个天才的解决方案,它会在我的 github 项目中使用相同的库。