try ... catch没有捕获IllegalArgumentException

时间:2015-02-25 10:00:09

标签: java android

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;
}

2 个答案:

答案 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;
}

对我有用!