从服务向活动抛出自定义异常

时间:2009-11-26 00:19:20

标签: android exception service ipc

我目前正在开发Android上的XMPP应用程序,我正在思考从我的服务中向我的活动抛出不同类型的Exception而不是RemoteException的最佳方式。

因为看起来不可能抛出使用IPC的RemoteException(你不能声明在你的.aidl中抛出任何东西),我只看到两个解决方案:

  • 为我的活动创建一个监听器来监听我的自定义XMPP异常,实际上它不会被抛出,而只是作为实现Parcelable协议的通常对象发送。

  • 抓住我的XMPPException并抛出一个RemoteException(用我的XMPPException更新内容) - 但在这种情况下,我怎么能知道我的活动是XMPP还是真正的RemoteException?通过标记异常的名称并在我的活动中解析它?这真是血腥。

你知道吗?我是否遗漏了SDK文档中的内容?

感谢。

3 个答案:

答案 0 :(得分:5)

如果#1表示我认为它的作用,我会使用它 - 让服务捕获异常并在由活动创建和提供的AIDL定义的回调对象上调用方法。

您可以从我的一本书中查看此clientservice项目中该技术的示例。

答案 1 :(得分:3)

看起来我们可以抛出从RemoteException派生的自定义异常。因此,您可以拥有XMPPRemoteException,或者只是一个包含原始异常的通用MyRemoteException。以下是第二种情况的演示:

服务器:

try {
    ...
}
catch(XMPPException e) {
    throw new MyRemoteException(e);
}

客户端:

try {
    service.someCall();
}
catch(MyRemoteException e) {
    rethrow(e);
}

帮助方法:

private void rethrow(MyRemoteException e) throws Exception {
    if(e.innerException instanceof XMPPException)
        throw (XMPPException)e.innerException;
    else
        throw e.innerException;
}

例外:

public class MyRemoteException extends RemoteException {
    private static final long serialVersionUID = 1L;
    public Exception innerException;

    public MyRemoteException() {}

    public MyRemoteException(Exception innerException) {
        this.innerException = innerException;
    }
}

答案 2 :(得分:0)

我认为无法实现“从服务向活动中抛出自定义异常”。 查看Parcel的资源:

    /**
 * Use this function for customized exception handling.
 * customized method call this method for all unknown case
 * @param code exception code
 * @param msg exception message
 */
public final void readException(int code, String msg) {
    switch (code) {
        case EX_SECURITY:
            throw new SecurityException(msg);
        case EX_BAD_PARCELABLE:
            throw new BadParcelableException(msg);
        case EX_ILLEGAL_ARGUMENT:
            throw new IllegalArgumentException(msg);
        case EX_NULL_POINTER:
            throw new NullPointerException(msg);
        case EX_ILLEGAL_STATE:
            throw new IllegalStateException(msg);
    }
    throw new RuntimeException("Unknown exception code: " + code
            + " msg " + msg);
}

所以我们可以知道我们可以抛出以上五个例外。

例如: 如果您的服务抛出IllegalArgumentException:

    @Override
public void addImage(final int align, final byte[] imageData) throws RemoteException {
    log("/// addImage ///");
    if (imageData == null) {
        throw new IllegalArgumentException("The second argument(image data) can not be empty!");
    }
...
}

您的客户可以抓住它:

            try {
                printer.addImage(0, null);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            }