【问题标题】:Recommended approach for handling errors across process using AIDL (Android)使用 AIDL (Android) 跨进程处理错误的推荐方法
【发布时间】:2013-03-14 07:19:07
【问题描述】:

我有一个活页夹服务和一个存在于不同进程中的客户端。使用 AIDL,当客户端调用我的远程 binder 服务时,有时我需要将错误(异常)转发回客户端。

但是,据我了解,这是不可能的。我尝试从我的活页夹服务中抛出一个“RemoteException”,看看会发生什么,我得到了

未捕获的远程异常! (尚不支持跨进程的异常。)

在我的日志中。

既然这看起来不可能,那么通知客户错误的最佳方法是什么?我在想我可以将我的 AIDL 转换为使用 C 风格的接口,在其中我只返回一个错误代码(成功时返回 0),但这看起来很难看。

有更好的方法吗?

【问题讨论】:

  • “我有一个活页夹服务和一个存在于不同进程中的客户端”——为什么?
  • 我为 AOSP(Android 开源项目)创建了一个系统服务,就像 PackageManager 一样,它一直在后台运行。我为我的客户创建了一个 AIDL 接口来与我的服务进行交互。
  • 好的,这很合理。您是否查看过其他系统服务如何处理它?我知道引发的一些异常实际上是由我们在 SDK 中视为系统服务的手动 Java 类引起的(例如,AccountManager)。但是我不得不认为系统进程中可能会出现一些异常情况,因此在某处必须有一个现有的模式。

标签: java android aidl android-binder


【解决方案1】:

如果出现错误,您的远程方法可以返回包含结果数据的Parcel 或异常。请参阅Parcel#writeException 方法。我相信这就是在对存在于另一个进程中的ContentProvider 执行操作时,Android 异常如何恢复。返回结果数据的方法有很多,包括使用Bundle 类。

您的管理器类可以通过解包和返回数据或抛出未打包的异常来隐藏实现细节,这样用户就不会与Parcel 交互。

Here is a link to the source for Parcel#writeException.

【讨论】:

  • 感谢您的回复。我喜欢这个想法,但不幸的是,它不支持自定义异常。我在想我可能会改变我所有的 AIDL 以返回一个 Bundle。 Bundle 将包含一个状态码 + 要返回的对象(如果有)。
  • 如果您在平台源代码中查看 Parcel#writeException 是如何实现的,它实际上非常简单(我在答案中添加了一个链接)。他们将表示异常类型的 int 写入 Parcel,如果没有发生异常,则写入 0,然后读取另一侧的 int 并抛出该异常。如果你遵循他们的模式,你可以抛出任何你喜欢的自定义异常。
猜你喜欢
  • 2011-02-22
  • 1970-01-01
  • 1970-01-01
  • 2014-05-30
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-30
相关资源
最近更新 更多