返回顶部
首页 > 资讯 > 精选 >Android AIDL通信DeadObjectException解决方法是什么
  • 855
分享到

Android AIDL通信DeadObjectException解决方法是什么

2023-07-05 11:07:43 855人浏览 安东尼
摘要

这篇文章主要介绍了Android aiDL通信DeadObjectException解决方法是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Android AIDL通信DeadObjec

这篇文章主要介绍了Android aiDL通信DeadObjectException解决方法是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Android AIDL通信DeadObjectException解决方法是什么文章都会有所收获,下面我们一起来看看吧。

    崩溃来源

    首先,这个崩溃的意思是,多进程在进行跨进程Binder通信的时候,发现通信的Binder对端已经死亡了。

    抛出异常的Java堆栈最后一行是BinderProxy.transactNative,所以我们从这个方法入手,看看崩溃是在哪里产生的。

    很显现,transactNative对应的是一个native方法,我们找到对应的native方法,在android_util_Binder.cpp中。

    static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,        jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException{    // 如果data数据为空,直接抛出空指针异常    if (dataObj == NULL) {        jniThrowNullPointerException(env, NULL);        return JNI_FALSE;    }    // 将Java层传入的对象转换为c++层的指针,如果转换出错,中断执行,返回JNI_FALSE    Parcel* data = parcelForJavaObject(env, dataObj);    if (data == NULL) {        return JNI_FALSE;    }    Parcel* reply = parcelForJavaObject(env, replyObj);    if (reply == NULL && replyObj != NULL) {        return JNI_FALSE;    }    // 获取C++层的Binder代理对象指针    // 如果获取失败,会抛出IllegalStateException    IBinder* target = getBPNativeData(env, obj)->mObject.get();    if (target == NULL) {        jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");        return JNI_FALSE;    }    // 调用BpBinder对象的transact方法    status_t err = target->transact(code, *data, reply, flags);    // 如果成功,返回JNI_TRUE,如果失败,返回JNI_FALSE    if (err == NO_ERROR) {        return JNI_TRUE;    } else if (err == UNKNOWN_TRANSACTION) {        return JNI_FALSE;    }    // 处理异常情况的抛出    signalExceptionForError(env, obj, err, true , data->dataSize());    return JNI_FALSE;}

    可以看到,这个方法主要做的事情是:

    • Java层传入的data,转换成C++层的指针

    • 获取C++层的Binder代理对象

    • 调用BpBinder对象的transact方法

    • 处理transact的结果,抛出异常

    接下来我们看看,BpBindertransact方法。

    status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){    // 首先判断Binder对象是否还存活,如果不存活,直接返回DEAD_OBJECT    if (mAlive) {            ...            status = IPCThreadState::self()->transact(binderHandle(), code, data, reply, flags);            return status;    }    return DEAD_OBJECT;}

    transact的具体方法,我们这里先不讨论。我们可以看到,在这里会判断当前的Binder对象是否alive,如果不alive,会直接返回DEAD_OBJECT的状态。

    返回的结果,在android_util_BindersignalExceptionForError中处理。

    void signalExceptionForError(JNIEnv* env, jobject obj, status_t err,        bool canThrowRemoteException, int parcelSize){       // 省略其他异常处理的代码        ....        case DEAD_OBJECT:            // DeadObjectException is a checked exception, only throw from certain methods.            jniThrowException(env, canThrowRemoteException                    ? "android/os/DeadObjectException"                            : "java/lang/RuntimeException", NULL);            break;}

    这个方法,其实包含非常多异常情况的处理。为了看起来更清晰,这里我们省略了其他异常的处理逻辑,只保留了DEAD_OBJECT的处理。可以很明显的看到,在这里我们抛出了DeadObjectException异常。

    解决方法

    通过前面的源码分析,我们知道DeadObjectException是发生在,当我们调用transact接口发现Binder对象不再存活的情况。

    解决方案也很简单,就是当这个Binder对象死亡之后,不再调用transact接口。

    方法1 调用跨进程接口之前,先判断Binder是否存活

    这个方案比较简单粗暴,就是在多有调用跨进程接口的地方,都加一个Binder是否存活的判断。

            if (mService != null && mService.asBinder().isBinderAlive()) {            mService.test();        }

    我们来看下isBinderAlive源码,就是判断mAlive标志位是否为0。

    bool BpBinder::isBinderAlive() const{    return mAlive != 0;}

    方法2 监听Binder死亡通知

    先初始化一个DeathRecipient,用来监听死亡通知。

        private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {        @Override        public void binderDied() {            // 解绑当前监听,重新启动服务            mService.asBinder().unlinkToDeath(mDeathRecipient, 0);            if (mService != null)                bindService(new Intent("com.service.bind"), mService, BIND_AUTO_CREATE);        }    };

    在这个死亡监听里,我们可以选择几种处理方式:

    • 什么都不做,直接将mService设置为空

    • 再次尝试启动和绑定服务

    onServiceConnected方法中,注册死亡监听:

    public void onServiceConnected(ComponentName name, IBinder service) {              mService = IServiceInterface.Stub.asInterface(service);         //获取服务端提供的接口    try {        // 注册死亡代理        if(mService != null){            service.linkToDeath(mDeathRecipient, 0);         }           } catch (RemoteException e) {        e.printStackTrace();    }}

    关于“Android AIDL通信DeadObjectException解决方法是什么”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“Android AIDL通信DeadObjectException解决方法是什么”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网精选频道。

    --结束END--

    本文标题: Android AIDL通信DeadObjectException解决方法是什么

    本文链接: https://lsjlt.com/news/351246.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    猜你喜欢
    • Android AIDL通信DeadObjectException解决方法是什么
      这篇文章主要介绍了Android AIDL通信DeadObjectException解决方法是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Android AIDL通信DeadObjec...
      99+
      2023-07-05
    • Android AIDL通信DeadObjectException解决方法示例
      目录崩溃来源解决方法方法1 调用跨进程接口之前,先判断Binder是否存活方法2 监听Binder死亡通知总结崩溃来源 使用过AIDL进行跨进程通信的同学,肯定遇到过DeadObj...
      99+
      2023-03-09
      Android AIDL通信 Android AIDL DeadObjectException
    • Android编程实现AIDL(跨进程通信)的方法详解
      本文实例讲述了Android编程实现AIDL(跨进程通信)的方法。分享给大家供大家参考,具体如下: 一. 概述: 跨进程通信(AIDL),主要实现进程(应用)间数据共享功能。 ...
      99+
      2022-06-06
      进程 方法 aidl 通信 Android
    • android多进程通信的方法是什么
      Android中多进程通信的方法有以下几种:1. 使用Messenger:Messenger是一种轻量级的进程间通信(IPC)机制,...
      99+
      2023-10-10
      android
    • android多线程通信的方法是什么
      在Android中,多线程通信可以使用以下几种方法:1. Handler:Handler是用于在不同线程之间传递消息的机制。可以在主...
      99+
      2023-08-18
      android
    • vue的通信方法是什么
      今天小编给大家分享一下vue的通信方法是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。通信方法:1、子组件设置props...
      99+
      2023-07-04
    • Android 使用【AIDL】调用外部服务的解决方法
      在Android 中有一种服务说是服务其实倒不如说是一个接口,这个接口名为:Android Interface Definition Language ,这个接口可提供跨进程访...
      99+
      2022-06-06
      调用 方法 aidl Android
    • Java NIO Socket通信的方法是什么
      这篇文章主要讲解了“Java NIO Socket通信的方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java NIO Socket通信的方法是什么”吧!服务器代码:import&...
      99+
      2023-06-17
    • Linux进程通信的方法是什么
      本篇内容介绍了“Linux进程通信的方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Linux进程通信具体方法1.管道管道分为有名管...
      99+
      2023-06-28
    • c++串口通信的方法是什么
      在C++中进行串口通信,通常需要使用串口通信库来实现。其中,常用的串口通信库包括Boost.Asio和Qt Serial Port等...
      99+
      2024-04-02
    • android网络通信机制是什么
      Android网络通信机制是指Android系统中用于实现网络通信功能的一系列机制和API。Android系统提供了多种网络通信方式...
      99+
      2023-08-26
      android
    • android读取短信的方法是什么
      Android读取短信的方法可以通过使用 BroadcastReceiver 和 ContentResolver 两种方式来实现。1...
      99+
      2023-08-12
      android
    • angular模块间通信的方法是什么
      在Angular中,模块间通信的方法有多种,下面是一些常用的方法:1. 通过共享服务进行通信:创建一个共享服务,可以在多个模块中注入...
      99+
      2023-10-11
      angular
    • docker容器间通信的方法是什么
      Docker容器间通信的方法有以下几种: 使用容器名称或ID进行通信:每个Docker容器都有一个唯一的名称或ID,可以使用这个...
      99+
      2023-10-25
      docker
    • golang进程间通信的方法是什么
      Golang中可以使用多种方式进行进程间通信,包括:1. Channel(通道):Golang的Channel是一种用于在协程之间进...
      99+
      2023-08-23
      golang
    • java线程间通信的方法是什么
      Java线程间通信的方法有以下几种: 使用共享变量:多个线程共享同一个变量,通过对变量的读写操作来实现线程间的通信。例如,一个线程...
      99+
      2023-10-28
      java
    • 常见的Linux进程通信方法是什么
      这篇文章主要为大家分析了常见的Linux进程通信方法是什么的相关知识点,内容详细易懂,操作细节合理,具有一定参考价值。如果感兴趣的话,不妨跟着跟随小编一起来看看,下面跟着小编一起深入学习“常见的Linux进程通信方法是什么”的知识吧。进程虽...
      99+
      2023-06-28
    • winform多个串口通信的方法是什么
      在Winform中,实现多个串口通信可以通过以下步骤和方法来实现: 创建多个SerialPort对象:首先在Winform中创建...
      99+
      2024-04-02
    • Flutter web bridge通信方式是什么
      这篇文章主要介绍“Flutter web bridge通信方式是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Flutter web bridge通信方式...
      99+
      2023-07-05
    • c++多进程通信实现的方法是什么
      C++多进程通信可以通过以下几种方法实现: 管道(Pipe):在父进程中创建管道,然后通过fork()系统调用创建子进程,父子进...
      99+
      2024-04-02
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作