Android中binderDied()以及"Unknown binder error code" 出现的原因说明

本文深入剖析Android系统中的Binder机制,探讨binderDied()方法的触发条件及未知Binder错误0xfffffff7的成因,帮助开发者有效避免和解决相关问题。
 

                                                                                                                                                              转载请注明出处:http://blog.youkuaiyun.com/qinjuning

 

 

                   Binder机制是Android系统进程间通信的核心机制,它很大而且很复杂,不过对它有一定程度的理解和掌握是真正接触    

          Android核心的必备。网上关于它的介绍很多,希望大家能耐着性子认真地学习Binder机制的实现。在此,给大家分享一个

         我认为挺好地学习Binder机制基础的博客《Android系统中Binder机制的分析系列》,希望对大家有用。 本来也准备自己

          写点关于Binder机制的,但无奈自己的理解程度很肤浅,只好放弃了。

 

                   自己从事的模块开发采用了Binder机制进行功能的开发,对Binder机制的不熟悉,导致了很多Bug的出现,可谓“一Bug

         未解,一Bug又起”,伤脑筋。今天对Binder运用过程中可能出现的两个问题做下总结,希望帮大家有所启发。

 

 

  为了下面叙述的清楚,假设我们存在如下的Binder交互对象:

 

                                  

                    

 

  1 、 binderDied()方法的触发时机

         当客户端对象A死掉时或者其他情况导致该Binder发生结束了,就会回调binderDied()方法,用户可以在这个方法里

     进行捕捉binder死掉。

    

      其方法原型在:IBinder.h文件中 (frameworks/base/include/binder/Ibinder.h)

          

 /**
     * This method allows you to add data that is transported through
     * IPC along with your IBinder pointer.  When implementing a Binder
     * object, override it to write your desired data in to @a outData.
     * You can then call getConstantData() on your IBinder to retrieve
     * that data, from any process.  You MUST return the number of bytes
     * written in to the parcel (including padding).
     */
    class DeathRecipient : public virtual RefBase
    {
    public:
        virtual void binderDied(const wp<IBinder>& who) = 0;
    };

 

      通常而言,我们可以在服务端BnXXX 里实现该虚函数去捕获Binder死掉事件,例如:

 

//Binder机制服务端的具体实现类
class BnXXX: public BnInterface<IXX>
{
public:
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);
                                    
    //当Binder机制的客户端死掉,导致了该Binder结束,会回调此方法                                
    void FMRadio::binderDied(const wp<IBinder>& who) {
        //输出该Binder进程所在的信息 包括进程Id(pid)等
        LOGD("binderDied() 1 %p, tid %d, calling tid %d", who.unsafe_get(), gettid(),
                           IPCThreadState::self()->getCallingPid());        
        // do something 
    }
}      



     

  2、 Unknown binder error code 0xfffffff7 出现的原因。

             

                当客户端与服务端正在通过Binder机制交互时,例如A正在通过Binder机制与B对象进行交互,即A请求B do something,

       这个过程中如果Binder机制发生了异常,导致A与B的交互不能正常进行,例如代码中显示调用System.exit(0)结束应用程序

        (说明:System.exit(0)方法会 清空该Process的一切资源,包括Activity、Service、BroadcastReceiver等资源,Binder交互

      也结束),系统就打印如下Log信息:“Error: JavaBinder  Unknown binder error code. 0xfffffff7”。接下来,C++层会调用

       binderDied() 法,其Binder客户端也死掉了,。

 

 

 

    最后,希望大家在此基础上能少找些弯路,多解几个Bug吧 ,善莫大焉 !

 

 

 

<think>根据给定的错误信息,用户遇到的是关于Android系统NativeCrashListener的异常,具体错误是“java.lang.IllegalArgumentException: Unknown option --full”。同时,用户提供的引用内容显示了一个NativeCrashListener在处理报告时出现的异常堆栈,其中包含“read failed: EAGAIN”错误。但是,用户当前的错误信息与引用中的错误并不完全相同,用户当前的错误集中在“Unknown option --full”上。 用户的需求是解决错误代码'UNKNOWN',错误信息为“Exception occurred while dumping: java.lang.IllegalArgumentException: Unknown option --full”。 分析: 该错误发生在尝试执行某个dump操作时,使用了不被识别的选项`--full`。这可能是由于使用了错误的命令或工具版本不匹配导致的。 可能的场景: 1. 在Android开发或调试过程中,使用了`adb`命令或者Android Studio中的某个工具,试图获取dump信息(如内存 dump、系统信息dump等)。 2. 使用的命令中包含了`--full`选项,但该选项在当前版本的工具中不被支持。 常见的相关命令: - `adb bugreport`:生成一个bug报告。 - `adb shell dumpsys`:获取系统服务信息。 - `adb dumpstate`:获取设备状态信息。 然而,从错误信息来看,具体是哪个命令使用了`--full`选项并不明确。但根据经验,`adb bugreport`命令在旧版本的Android中可能不支持`--full`选项,或者选项名称有变化。 解决方案步骤: 1. 确认命令和选项的正确性: 检查所使用的命令是否拼写正确,以及当前设备或工具的版本是否支持`--full`选项。 2. 检查工具版本: 例如,如果是使用`adb`命令,可以通过`adb --version`查看版本。较新的adb版本可能支持该选项,而较旧的版本可能不支持。 3. 查看帮助文档: 使用`adb help`或者具体命令后加`--help`(如`adb bugreport --help`)来查看支持的选项。 4. 替代方案: 如果不支持`--full`选项,可以考虑使用其他选项或者不使用该选项。例如,`adb bugreport`命令在没有选项的情况下会生成完整的报告,而`--full`可能是一个冗余选项(在最新版本中已经被废弃或改名)。 5. 更新工具: 如果是因为adb版本过旧,可以尝试更新Android SDK Platform-Tools到最新版本。 6. 具体错误上下文: 由于错误信息来自NativeCrashListener,这通常发生在系统内部处理native crash报告时。所以也可能是系统内部的一个命令调用错误。如果是系统内部的问题,可能需要检查系统更新或修复系统镜像。 但是,用户提供的错误信息中出现了“Exception occurred while dumping”,并且有明确的参数错误(IllegalArgumentException),这更可能是由于用户自己执行的命令导致的,而不是系统内部错误。因为系统内部命令通常不会使用错误的选项。 因此,重点应放在用户自己执行的命令上。 根据用户错误信息中的“java.lang.IllegalArgumentException: Unknown option --full”,我们可以推测,可能是在执行类似以下的命令: adb shell dumpsys --full 或者 adb bugreport --full 但是,在标准的adb命令中,`dumpsys`并不支持`--full`选项(尽管有一些子服务支持`--full`选项,但直接在`dumpsys`后使用是不支持的)。同样,`adb bugreport`命令在Android 8.0(API级别26)及以上版本支持`--full`选项,但在较低版本中不支持。 因此,具体的解决办法: 1. 对于`dumpsys`命令: - 如果用户是想获取某个服务的完整信息,应该先指定服务名,然后查看该服务是否支持`--full`选项。例如:`adb shell dumpsys activity --full`(但并非所有服务都支持)。 - 如果直接在`dumpsys`后使用`--full`,则会报错,因为`dumpsys`本身不接受该选项。 2. 对于`bugreport`命令: - 在Android 8.0及以上版本,`adb bugreport`命令支持`--full`选项,用于包含所有可能的调试信息(包括dumpstate、dumpsys等)。但在较低版本中,该选项不存在。 - 如果用户的目标设备版本较低,应该去掉`--full`选项,直接使用`adb bugreport`。 建议用户确认Android设备的版本以及adb版本,并调整命令。 如果用户并没有显式执行命令,而是通过IDE(如Android Studio)的某个功能触发,那么可能是IDE中的插件或工具使用了过时的命令选项。在这种情况下,建议更新IDE和插件。 由于用户没有提供具体的命令,我们可以给出一般性的解决步骤: 步骤: 1. 检查命令:确认是否在命令中使用了`--full`选项,以及该命令是否支持该选项。 2. 查看帮助:运行命令加`--help`查看支持的选项。 3. 更新工具:更新adb到最新版本(从官网下载最新版的Platform-Tools)。 4. 去掉`--full`选项:尝试不使用该选项,看是否能够正常运行。 5. 如果问题发生在程序内部(非用户手动执行命令),则需要检查代码中调用相关命令的地方,确保选项正确。 如果用户是在编写程序时调用某个命令,那么需要捕获该异常并处理不支持的选项。 根据用户给出的引用[1]和[2],它们似乎与当前错误没有直接关联,但引用[1]提到了NativeCrashListener在处理native crash报告时出现了读取错误(EAGAIN),这可能与系统繁忙或资源暂时不可用有关,但用户当前的错误是参数错误,所以应该分开处理。 因此,针对当前错误,解决方案总结: - 错误原因:使用了不被支持的选项`--full`。 - 解决方法:移除该选项或更新工具以支持该选项。 如果用户的问题仍然存在,需要更多的上下文信息。 生成相关问题: 1. 如何更新Android SDK Platform-Tools? 2. `adb bugreport`命令在不同Android版本中的区别? 3. 如何查看Android设备的系统版本? 4. `dumpsys`命令的常用用法有哪些? 5. 如何在代码中捕获并处理IllegalArgumentException异常? 回答用户: </think>根据您提供的错误信息,核心问题在于执行 dump 操作时使用了不被识别的 `--full` 选项。以下是系统化的解决方案: ### 错误原因分析 1. **无效参数**:`java.lang.IllegalArgumentException: Unknown option --full` 表明命令中使用了当前环境不支持的选项 `--full`,常见于以下场景: - ADB 或系统工具版本过旧(低于 Android 8.0) - 工具链版本与设备系统版本不兼容 - 命令语法在特定设备上已被弃用[^1] 2. **上下文关联**:结合引用[1]的 `NativeCrashListener` 异常,该错误通常发生在系统级诊断工具(如 `dumpsys`、`bugreport`)尝试生成完整报告时,因参数不匹配导致进程崩溃[^1][^2]。 --- ### 解决方案 #### 第一步:验证命令兼容性 1. **检查 Android 版本**: - 若设备系统版本 **< Android 8.0 (API 26)**,`--full` 选项未被引入,需改用传统命令: ```bash adb shell dumpsys # 替代 adb shell dumpsys --full ``` - 通过 `adb shell getprop ro.build.version.release` 查询设备系统版本。 2. **更新 ADB 工具链**: 升级 Android SDK Platform-Tools 至最新版(≥ v34.0.0): ```bash sdkmanager --update sdkmanager "platform-tools" ``` #### 第二步:修正命令语法 - **场景 1:生成完整系统报告** 使用标准 `bugreport` 替代错误命令: ```bash adb bugreport output.zip # 自动包含完整诊断数据 ``` - **场景 2:获取特定服务诊断** 明确服务名并移除无效选项(如 `--full`): ```bash adb shell dumpsys activity # 示例:获取Activity服务诊断 ``` #### 第三步:处理系统级崩溃(引用[1]关联方案) 若错误源自系统进程崩溃(如 `NativeCrashListener`): 1. **清除缓存数据**: ```bash adb shell pm clear com.android.settings ``` 2. **重启系统服务**: ```bash adb shell stop && adb shell start ``` --- ### 关键验证点 1. **版本兼容矩阵**: | Android 版本 | `--full` 支持 | 替代方案 | |--------------|---------------|-------------------| | < 8.0 | ❌ | `adb bugreport` | | ≥ 8.0 | ✅ | 直接使用 | 2. **诊断工具链更新**: ```bash adb --version # 需 ≥ 34.0.0 ``` --- ### 相关问题 1. 如何获取 Android 设备的完整系统诊断报告? 2. `adb shell dumpsys` 和 `adb bugreport` 有什么区别? 3. 系统服务崩溃时如何修复 `NativeCrashListener` 错误? 4. Android 调试桥(ADB)的常用命令有哪些? 5. 如何解决参数不匹配导致的 `IllegalArgumentException` 异常? [^1]: NativeCrashListener 异常通常由系统资源冲突或命令兼容性问题触发 [^2]: 进程信息与系统服务交互的底层参数需严格匹配设备 API 级别
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值