linkToDeath机制了解和使用

2023-11-17

转自:http://www.jianshu.com/p/e38f08e34686

 
 

在学习Binder和AIDL的过程中遇到的一些有意思的事情~! linkToDeath机制,我们先看看官网如何介绍:

When working with remote objects, you often want to find out when they are no longer valid. There are three ways this can be determined: The transact() method will throw a RemoteException exception if you try to call it on an IBinder whose process no longer exists. The pingBinder() method can be called, and will return false if the remote process no longer exists. The linkToDeath() method can be used to register a IBinder.DeathRecipient with the IBinder, which will be called when its containing process goes away.

总结:我们可以通过三种方式来检测远程对象是否存活。

  • 调用远程方法的时候捕获RemoteException(DeadObjectException);
  • 调用IBinder的pingBinder()进行检测;
  • 实现IBinder.DeathRecipient接口回调;

Binder意外中断

往往是由于服务端进程意外停止了,这时我们需要重新连接服务。 那么我们可以使用linkToDeath机制,如果使用bindService那么还可以通过ServiceConnection.onServiceDisconnected方法进行重连。

捕获RemoteException

在调用远程服务的时候,如果服务挂掉,那么我们客户端会接受到抛出的RemoteException异常,监听该异常进行处理。

android.os.DeadObjectException
    at android.os.BinderProxy.transact(Native Method)
    at com.tzx.aidlinout.aidl.IBookManager$Stub$Proxy.addInBook(IBookManager.java:159)
    at com.tzx.aidlinout.MainActivity.onClick(MainActivity.java:117)
    at android.view.View.performClick(View.java:3514)
    at android.view.View$PerformClick.run(View.java:14125)
    at android.os.Handler.handleCallback(Handler.java:605)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4439)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:787)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:554)
    at dalvik.system.NativeStart.main(Native Method)

pingBinder进行检测

pingBinder()方法会返回当前远程服务的状态(true|false)

IBinder.DeathRecipient

实现了IBinder.DeathRecipient接口的参数调用linkToDeath()方法,可以在binderDied方法中处理中断逻辑。

binder.linkToDeath(new IBinder.DeathRecipient() {
    @Override
    public void binderDied() {
        Log.d("binder", "binderDied calling~!");
    }
}, 0);

总结

先看下边的log,从中我们可以总结出以上4中Binder中断处理方法的执行顺序:

linkToDeath > onServiceDisconnected > pingBinder > transact()

//调用远程服务
binder.pingBinder = true
Binder Thread #2    //远程服务的当前线程名称
//kill远程服务存在的进程
binderDied calling~!
onServiceDisconnected
binder.pingBinder = false
android.os.DeadObjectException
    at android.os.BinderProxy.transact(Native Method)
    at com.tzx.aidlinout.aidl.IBookManager$Stub$Proxy.addInBook(IBookManager.java:159)
    at com.tzx.aidlinout.MainActivity.onClick(MainActivity.java:117)
    at android.view.View.performClick(View.java:3514)
    at android.view.View$PerformClick.run(View.java:14125)
    at android.os.Handler.handleCallback(Handler.java:605)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4439)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:787)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:554)
    at dalvik.system.NativeStart.main(Native Method)

扩展

这里讲一个Android源码中的类:RemoteCallbackList。
它在内部对列表中的每一个数据实现了Callback。而Callback实现了IBinder.DeathRecipient接口。

public class RemoteCallbackList<E extends IInterface> {
    ArrayMap<IBinder, Callback> mCallbacks
            = new ArrayMap<IBinder, Callback>();
    private Object[] mActiveBroadcast;
    private int mBroadcastCount = -1;
    private boolean mKilled = false;

    private final class Callback implements IBinder.DeathRecipient {
        final E mCallback;
        final Object mCookie;

        Callback(E callback, Object cookie) {
            mCallback = callback;
            mCookie = cookie;
        }

        public void binderDied() {
            synchronized (mCallbacks) {
                mCallbacks.remove(mCallback.asBinder());
            }
            onCallbackDied(mCallback, mCookie);
        }
    }
    /******其他代码省略*******/
}


作者:静默加载
链接:http://www.jianshu.com/p/e38f08e34686
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linkToDeath机制了解和使用 的相关文章

随机推荐

  • TypeScript(五)类型别名及类型符号

    目录 引言 类型别名 基本用法 字面量类型 数字字面量 字符串字面量 布尔字面量 空字面量 枚举字面量 类型符号 联合类型 交叉类型 类型断言 尖括号 as关键字 非空断言 类型保护 typeof instanceof 类型谓词 索引类型
  • 解决 IProgress not found. Please update jupyter and ipywidgets. 问题

    解决 IProgress not found Please update jupyter and ipywidgets 问题 一 报错 IProgress not found Please update jupyter and ipywid
  • web服务搭建

    Python 吹爆Python 1行代码搭建Web服务器30行代码实现服务器的文件上传下载 需求 手机每日下载图片 然后需经过本人编写的Python脚本处理一遍 再返回到手机上 个人电脑不能保证时刻开机在线 自己也不可能一直在电脑旁边 故欲
  • Firebug 1.9新特性指南

    Firebug 1 9新特性指南 FireBug1 9发布了 引入了很多新特性 一 Firebug兼容的Firefox版本 Firefox4兼容Firebug1 7 3 Firefox5 11兼容Firebug1 9 Firefox12兼容
  • 【Python 协程详解】

    0 前言 前面讲了线程和进程 其实python还有一个特殊的线程就是协程 协程不是计算机提供的 计算机只提供 进程 线程 协程是人工创造的一种用户态切换的微进程 使用一个线程去来回切换多个进程 为什么需要协程 导致Python不能充分利用多
  • 分布式协议与算法——Paxos算法

    目录 Paxos算法 Basic Paxos算法 三种角色 如何达成共识 协商过程 小结 Multi Paxos算法 关于 Multi Paxos 的思考 领导者 优化Basic Paxos Chubby 的 Multi Paxos 实现
  • 解决Elasticsearch查询默认最大值返回10000

    文章目录 1 问题描述 1 描述 2 分析 2 解决方案 1 更改当前索引最大查询条数 max result window 2 能查出数据 但是total依然还是1000 更改track total hits 3 当java使用时应该 4
  • android webview 加载本地html并且解决多图卡顿问题

    使用webview加载本地html 因为本地html使用多张图片 滑动起来卡顿 解决方法如下 把文件夹放入assets文件夹下 Activity加载 WebView wView WebView findViewById R id webvi
  • PANet:基于金字塔注意力网络的图像超分辨率重建(全代码)

    PANet 基于金字塔注意力网络的图像超分辨率重建 本文为全代码 原文请看 传送门 import torch import torch nn as nn import torch nn functional as F from torch
  • 运维实战案例之文件已删除但空间不释放问题解析

    1 错误现象 运维的监控系统发来通知 报告一台服务器空间满了 登陆服务器查看 根分区确实没有空间了 如下图所示 这里首先说明一下服务器的一些删除策略 由于Linux没有回收站功能 我们的线上服务器所有要删除的文件都会首先移动到系统 tmp目
  • 请使用mysql连接池

    在初次使用 python 的 pymysql工具包连接 mysql数据库 的时候 总是发生数据库连接失败的情况发生 经过多方确认 发现这种情况不是自己的连接方式错了 而是mysql数据库服务器因为网络出现闪断 导致在查询的时候发生连接出错的
  • 深度学习与计算机视觉[CS231N] 学习笔记(4.1):反向传播(Backpropagation)

    在学习深度学习的过程中 我们常用的一种优化参数的方法就是梯度下降法 而一般情况下 我们搭建的神经网络的结构是 输入 权重矩阵 损失函数 如下图所示 而在给定输入的情况下 为了使我们的损失函数值达到最小 我们就需要调节权重矩阵 使之满足条件
  • DQN理论基础及其代码实现【Pytorch + CartPole-v0】

    DQN算法的理论基础 基于动态规划方法 基于蒙特卡罗方法和基于时间差分的方法都有一个基本的前提条件 状态空间和动作空间是离散的 而且状态空间和动作空间不能太大 这些强化学习方法的基本步骤是先评估值函数 再利用值函数改善当前的策略 这时的值函
  • ROS rosdep update 出错方法 不需要翻墙切换之类的解决方法 ‘https://raw.githubusercontent.com/ros/rosdistro/master/inde

    系统 ubuntu18 rosdep update参考的这篇文章 https blog csdn net weixin 43311920 article details 114796748 utm source app app versio
  • HBase NoSQL数据库详解

    一 HBase简介 HBase是Hadoop的生态系统 是建立在Hadoop文件系统 HDFS 之上的分布式 面向列的数据库 通过利用Hadoop的文件系统提供容错能力 如果你需要进行实时读写或者随机访问大规模的数据集的时候 请考虑使用HB
  • Android获取当前位置的三种方式及其使用方法

    1 GPS定位 2 基站定位 此类位置的获取有赖于手机无线通讯信号 当手机处在信号覆盖范围内 手机可以获得该区域 即通讯术语中的 小区 的识别号 因为这些识别号是惟一的 因此可以将识别号和地理坐标对应起来 因此根据识别号就可以知道地理位置
  • Unity3D 使用TextMeshPro中文字体

    这一篇简单描述一下如果使用unity的一个强大的文字组件或者插件 开始 第一步 如果你是unity2018版本的话 在编辑器里面的AssetPackgeManager找到这个插件 没有的话就在搜索框里面搜索下载 如果你是低于2018的版本
  • Xilinx ISE系列教程(8):读取FPGA芯片唯一ID号

    文章目录 toc 应用场景 方法1 通过JTAG读取 方法2 调用原语读取 DNA PORT原语的使用 DNACLK频率注意 本文是Xilinx ISE系列教程的第8篇文章 用过单片机的朋友都知道 单片机芯片内部都有一串序列号 比如STM3
  • OkHttp库简介

    一直以来 Java并没有什么比较好用的HTTP库 JDK自带的HTTP类又非常旧 难以使用 今天我发现了一个使用比较广泛的OkHttp库 它在安卓和Java领域都有使用 在Github上的星数有两万多 所以我们可以放心的使用 安装 先来看看
  • linkToDeath机制了解和使用

    转自 http www jianshu com p e38f08e34686 在学习Binder和AIDL的过程中遇到的一些有意思的事情 linkToDeath机制 我们先看看官网如何介绍 When working with remote