我尝试这样做:连接到USB设备并获得打开(或失败)的连接。我根据我发现的例子和解释做了逻辑,但是我在等待许可授予方面遇到了问题。首先,我尝试了一个好的"使用wait()+ notifyAll()的方式,比我尝试使用检查的直接循环,但是两次等待方法(waitConnection())都阻塞了我给它的超时,并且只有在收到消息之后。所以我尝试了这两个版本。
等待/ notifyAll的:
public UsbConnector startConnection(Context context) {
BroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (syncObj) {
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (device != null) {
if (device.getVendorId() == vendorId && device.getProductId() == productId) {
connection = usbManager.openDevice(device);
connectedDevice = device;
}
}
}
syncObj.notyfyAll();
}
}
}
};
try {
usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
for (final UsbDevice device : usbManager.getDeviceList().values()) {
if (device.getVendorId() == this.vendorId && device.getProductId() == this.productId) {
context.registerReceiver(receiver, new IntentFilter(ACTION_USB_PERMISSION));
usbManager.requestPermission(device,
PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0));
break;
}
}
} catch (Exception e) {
}
return this;
}
public UsbDeviceConnection waitConnection(int timeout) {
try {
Thread.sleep(10, 0);
syncObj.wait(timeout);
} catch (InterruptedException e) {
}
return getConnection();
}
直接循环
public UsbConnector startConnection(Context context) {
BroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (device != null) {
if (device.getVendorId() == vendorId && device.getProductId() == productId) {
connection = usbManager.openDevice(device);
connectedDevice = device;
}
}
}
permissionRequested = false;
}
}
}
};
try {
permissionRequested = false;
usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
for (final UsbDevice device : usbManager.getDeviceList().values()) {
if (device.getVendorId() == this.vendorId && device.getProductId() == this.productId) {
permissionRequested = true;
context.registerReceiver(receiver, new IntentFilter(ACTION_USB_PERMISSION));
usbManager.requestPermission(device,
PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0));
break;
}
}
} catch (Exception e) {
}
return this;
}
public UsbDeviceConnection waitConnection(int timeout) {
int waited = timeout;
while (permissionRequested && waited > 0) {
try {
Thread.sleep(10, 0);
} catch (InterruptedException e) {
}
waited -= 10;
}
return getConnection();
}
所以在这两种情况下,根据日志,waitConnection()方法(在startConnection()之后立即被消费者调用)似乎阻止执行(我给它超时10秒,它被阻止了10秒),只有在它完成后,BroadcastReceiver才会收到消息。似乎requestPermission()不是异步(我认为是),但在这种情况下,startConnection()如何在接收到消息之前立即退出?我如何等待BroadcastReceiver获取消息?假设我不使用waitConnection()方法,我的消费者应该如何知道它何时可以开始检查连接可用性?
答案 0 :(得分:0)
“并且只有在完成后,BroadcastReceiver才会收到消息”
默认情况下,onReceived
回调在主线程上调用。听起来你也在主线程上调用waitConnection()
。由于waitConnection()
阻塞,主线程在waitConnection()
返回之前无法处理任何其他消息。这意味着在onReceived
超时之前不会调用waitConnection()
。
阻止主线程通常是一个坏主意。 Read here
相反,您可以onReceive
启动一项新活动,然后在获得USB许可后执行您需要执行的操作。这对你来说可能是也可能不是最好的解决方案,但无论如何,这里的关键是永远不要阻止主线程。