【问题标题】:Throw a custom exception from a service to an activity将自定义异常从服务抛出到活动
【发布时间】:2009-11-26 00:19:19
【问题描述】:

我目前正在开发 Android 上的 XMPP 应用程序,我正在考虑从我的服务中向我的活动抛出与 RemoteException 不同类型的异常的最佳方法。

由于使用 IPC 抛出 RemoteException 之外的其他东西似乎是不可能的(你不能声明在你的 .aidl 中抛出任何东西),我只看到两个解决方案:

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

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

你有什么想法吗?我是否遗漏了 SDK 文档中的某些内容?

谢谢。

【问题讨论】:

  • 如果他们为您工作,请不要忘记接受答案。它可以帮助未来的观众了解哪个答案对您的帮助最大。谢谢

标签: android exception service ipc


【解决方案1】:

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

您可以在我的一本书中的 clientservice 项目中看到该技术的示例。

【讨论】:

  • 是的,我查看了您的代码,我正在谈论这个问题。我会使用它,它必须是正确的方法。但是谷歌不允许我们抛出另一种异常,这有点奇怪。也许在 SDK 的未来版本中。谢谢你的建议:)
【解决方案2】:

看起来我们可以抛出从 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;
    }
}

【讨论】:

  • Service 同步处理请求时自定义异常是好的。如果请求是异步处理的,则将使用对客户端的回调(请参阅@commonsware.com 响应)。
  • E/JavaBinder(1544): *** 未捕获的远程异常! (跨进程尚不支持异常。)这种方法对我不起作用。
  • 它对我也不起作用。 MyRemoteException 将被框架捕获并记录下来,并在客户端生成一个新的不相关的 RemoteException。否决这个答案。
【解决方案3】:

我认为不可能实现“从服务向活动抛出自定义异常”。 查看 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();
            }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-24
    • 2018-07-03
    • 2017-11-18
    • 2016-10-24
    • 2023-03-19
    • 2011-10-06
    • 2011-05-30
    相关资源
    最近更新 更多