Android native层 DeathRecipient 死亡通知监听实现
本系列文章分析的安卓源码版本:【Android 10.0 版本】
此部分是在分析multimedia整体架构时由于该内容是常用实现内容,因此被抽出来单独进行分析。
要阅读本章节需有Binder机制实现原理的大致掌握,推荐可先补充另一章节内容:Android C++底层Binder通信机制原理分析总结【通俗易懂】
死亡通知是为了让Bp端能知道Bn端的生死状态
定义:DeathRecipient继承IBinder::DeathRecipient类,主要实现其binderDied()方法来处理死亡通知事件。
注册:binder->linkToDeath(mDeathRecipient)是为了将mDeathRecipient死亡通知注册到Binder上,并发送【BC_CLEAR_DEATH_NOTIFICATION】Binder任务命令给IPCThreadState去监听binder驱动的死亡通知。
Bp端只需覆写binderDied()方法,实现一些清除工作,则在Bn端Binder进程死亡后,会回调binderDied()方法进行相应处理。
1、根据该章节(【三】Android MediaPlayer整体架构源码分析 -【设置数据源】【Part 2】)第1小节的分析,可知其实现监听功能非常简单,在sp MediaPlayerService::Client::setDataSource_pre()方法中,关键实现代码如下:
// [frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp]
// 收集Binder对端进程(如相关Service服务进程)异常关闭通知事件集合
std::vector<DeathNotifier> deathNotifiers;
// 此处为监听媒体数据提取(即数据解析)解复用模块服务进程的异常关闭断开通知
// Listen to death of media.extractor service
// 从【multimedia整体架构】系列章节的类似代码处理分析可知,
// 此处功能即为:从服务注册管理中心获取名为【media.extractor】服务的Binder通信服务
sp<IServiceManager> sm = defaultServiceManager();
// 注意此处获取到的是Bp对象
sp<IBinder> binder = sm->getService(String16("media.extractor"));
if (binder == NULL) {
ALOGE("extractor service not available");
return NULL;
}
// 向该集合对象中添加监听的Binder进程
// 注意:此处是创建了DeathNotifier类的匿名对象加入到该集合中的处理,
// 调用的构造函数为:DeathNotifier(sp<IBinder> const& service, Notify const& notify),
// 第一个参数为binder,binder后面的全部是第二个参数,其实际上就是一个匿名方法的实现,
// 因为Notify就是一个方法引用【using Notify = std::function<void()>;】,
// 并且该匿名方法带有一个参数为【l = wp<MediaPlayerBase>(p)】即指针弱引用
// 【弱引用的原因是,不能影响其强引用对象指针的回收】
// 因此在监听到对端进程异常关闭后将会执行该匿名方法。
// 其具体实现原理,见第2小节分析
deathNotifiers.emplace_back(
binder, [l = wp<MediaPlayerBase>(p)]() {
// 被监听的进程异常关闭时,执行此匿名方法实现
// 将弱引用对象尝试进行提升为强引用对象
sp<MediaPlayerBase> listener = l.promote();
if (listener) {
ALOGI("media.extractor died. Sending death notification.");
listener->sendEvent(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED,
MEDIAEXTRACTOR_PROCESS_DEATH);
} else {
ALOGW("media.extractor died without a death handler.");
}
});
2、监听对端进程实现流程分析
DeathNotifier,对对端进程(如相关Service服务进程)异常关闭通知事件的监听实现处理:
DeathNotifier类声明:
// [/frameworks/av/media/libmediaplayerservice/DeathNotifier.h]
class DeathNotifier {
public:
using HBase = hidl::base::V1_0::IBase;
// 使用方法声明定义
using Notify = std::function<void()>;
DeathNotifier(sp<IBinder> const& service, Notify const& notify);
DeathNotifier(sp<HBase> const& service, Notify const& notify);
DeathNotifier(DeathNotifier&& other);
~DeathNotifier();
private:
// 注意该变量的声明,类模板 std::variant 表示一个类型安全的共享体(union)。
// 即行为和union大致相同,每次只可存在一种类型,该对象通过下标访问
std::variant<std::monostate, sp<IBinder>, sp<HBase>> mService;