在open-source Camera App中,我在以下代码中崩溃了
try {
// crash happens in next line:
PtpUsbConnection connection = new PtpUsbConnection(usbManager.openDevice(device), in, out,
device.getVendorId(), device.getProductId());
camera = new EosCamera(connection, listener, new WorkerNotifier(context));
}
catch (IllegalArgumentException e) {
Log.i(TAG, "IllegalArgumentException: camera was switched off? "+ e.getMessage());
e.printStackTrace();
return false;
}
catch (Exception e) {
Log.i(TAG, "Exception: camera was switched off? "+ e.getMessage());
e.printStackTrace();
return false;
}
崩溃产生以下日志
02-25 10:41:14.698 9238-9238/com.remoteyourcam.usb E/UsbManager﹕ exception in UsbManager.openDevice
java.lang.IllegalArgumentException: device /dev/bus/usb/001/008 does not exist or is restricted
at android.os.Parcel.readException(Parcel.java:1469)
at android.os.Parcel.readException(Parcel.java:1419)
at android.hardware.usb.IUsbManager$Stub$Proxy.openDevice(IUsbManager.java:373)
at android.hardware.usb.UsbManager.openDevice(UsbManager.java:308)
at com.remoteyourcam.usb.ptp.PtpUsbService.connect(PtpUsbService.java:238)
at com.remoteyourcam.usb.ptp.PtpUsbService.initialize(PtpUsbService.java:135)
at com.remoteyourcam.usb.MainActivity.onStart(MainActivity.java:232)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1171)
at android.app.Activity.performStart(Activity.java:5413)
at android.app.Activity.performRestart(Activity.java:5469)
at android.app.Activity.performResume(Activity.java:5474)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2945)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2984)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1335)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:149)
at android.app.ActivityThread.main(ActivityThread.java:5257)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:788)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:604)
at dalvik.system.NativeStart.main(Native Method)
有一个可重现的事件序列导致崩溃。具体来说:当应用程序(显然)没有预见到可能性时,在USB总线上切换摄像头。
我希望只是抓住这个例外,然后忽略它。
然而,即使代码明确捕获IllegalArgumentException
并且(对于良好的衡量标准)一般Exception
,应用程序仍然会继续崩溃。
为什么我的IllegalArgumentException
没有被抓住?
----更新:
openDevice()方法是Android库的一部分。它实际上似乎处理Exception
。
这是我的导入
package com.remoteyourcam.usb.ptp;
import java.util.Map;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.os.Handler;
import android.util.Log;
import com.remoteyourcam.usb.AppConfig;
import com.remoteyourcam.usb.ptp.Camera.CameraListener;
import com.remoteyourcam.usb.ptp.PtpCamera.State;
----更新2:
这是我在Android 18中看到的openDevice()
实现。据我所知,它处理了一般Exception
/**
* Opens the device so it can be used to send and receive
* data using {@link android.hardware.usb.UsbRequest}.
*
* @param device the device to open
* @return a {@link UsbDeviceConnection}, or {@code null} if open failed
*/
public UsbDeviceConnection openDevice(UsbDevice device) {
try {
String deviceName = device.getDeviceName();
ParcelFileDescriptor pfd = mService.openDevice(deviceName);
if (pfd != null) {
UsbDeviceConnection connection = new UsbDeviceConnection(device);
boolean result = connection.open(deviceName, pfd);
pfd.close();
if (result) {
return connection;
}
}
} catch (Exception e) {
Log.e(TAG, "exception in UsbManager.openDevice", e);
}
return null;
}
答案 0 :(得分:2)
异常发生在另一个线程中。
您正在异步初始化工作并将工作分派给另一个线程。您的代码仅在将Parcel分派给远程服务时捕获异常。
有关Android中远程过程调用的详细信息,您可能需要阅读Deep Dive into Binder。
答案 1 :(得分:0)
我用这个源代码得到了同样的情况,我发现了一个避免崩溃的技巧。只需修复您的代码
try {
// crash happens in next line:
PtpUsbConnection connection = new PtpUsbConnection(usbManager.openDevice(device), in, out,
device.getVendorId(), device.getProductId());
camera = new EosCamera(connection, listener, new WorkerNotifier(context));
}
catch (IllegalArgumentException e) {
Log.i(TAG, "IllegalArgumentException: camera was switched off? "+ e.getMessage());
e.printStackTrace();
return false;
}
catch (Exception e) {
Log.i(TAG, "Exception: camera was switched off? "+ e.getMessage());
e.printStackTrace();
return false;
}
到
try {
// crash happens in next line:
UsbDeviceConnection udc = usbManager.openDevice(device);
if (udc != null){
PtpUsbConnection connection = new PtpUsbConnection(udc, in, out,
device.getVendorId(), device.getProductId());
camera = new EosCamera(connection, listener, new WorkerNotifier(context));
}
}
catch (IllegalArgumentException e) {
Log.i(TAG, "IllegalArgumentException: camera was switched off? "+ e.getMessage());
e.printStackTrace();
return false;
}
catch (Exception e) {
Log.i(TAG, "Exception: camera was switched off? "+ e.getMessage());
e.printStackTrace();
return false;
}
对我有用!