Android面试:挂了三次的ServiceManager-工作原理,这次怎么也得整的明明白白

可以看到,当 ServiceManager 发生问题重启时,其他 healthd、zygote、media 等服务也会被重启。ServiceManager 服务启动后会执行 service_manager.c 的 main 函数,关键代码如下:

//frameworks/native/cmds/servicemanager/service_manager.c
int main(){
bs = binder_open(128*1024);
if (binder_become_context_manager(bs)) {

}

binder_loop(bs, svcmgr_handler);
return 0;
}

其中三个函数对应了 ServiceManager 初始化的三个关键工作:

  1. binder_open():打开 binder 驱动并映射内存块大小为 128KB
  2. binder_become_context_manager():将自己设置为 Binder “DNS” 管理者
  3. binder_loop():进入循环,等待 binder 驱动发来消息

下面分别来分析这三个函数,首先来看 binder_open() 是怎么打开 binder 驱动并映射内存的:

struct binder_state *binder_open(size_t mapsize){
struct binder_state *bs;
struct binder_version vers;
bs = malloc(sizeof(*bs));

//打开 binder 驱动,最终调用 binder_open() 函数
bs->fd = open(“/dev/binder”, O_RDWR | O_CLOEXEC);

//获取 Binder 版本,最终调用 binder_ioctl() 函数
ioctl(bs->fd, BINDER_VERSION, &vers)

//将虚拟内存映射到 Binder,最终调用 binder_mmap() 函数
bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);

return bs;
}

再来看 binder_become_context_manager() 是怎么将自己设置为 Binder “DNS 管理者的”:

int binder_become_context_manager(struct binder_state *bs){
//发送 BINDER_SET_CONTEXT_MGR 命令,最终调用 binder_ioctl() 函数
return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}

最后来看 binder_loop() 是怎么循环等待并处理 binder 驱动发来的消息:

void binder_loop(struct binder_state *bs, binder_handler func){
int res;
//执行 BINDER_WRITE_READ 命令所需的数据格式:
struct binder_write_read bwr;
uint32_t readbuf[32]; //每次读取数据的大小
readbuf[0] = BC_ENTER_LOOPER;
//先将 binder 驱动的进入循环命令发送给 binder 驱动:
binder_write(bs, readbuf, sizeof(uint32_t));
for (;😉 { //进入循环
bwr.read_size = sizeof(readbuf);
//读取到的消息数据存储在 readbuf
bwr.read_buffer = (uintptr_t) readbuf;
//执行 BINDER_WRITE_READ 命令读取消息数据
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
if (res < 0) {
ALOGE(“binder_loop: ioctl failed (%s)\n”, strerror(errno));
break;
}
//处理读取到的消息数据
res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);

}
}

BINDER_WRITE_READ 命令既可以用来读取数据也可以写入数据,具体是写入还是读取依赖 binder_write_read 结构体的 write_size 和 read_size 哪个大于 0,上面代码通过 bwr.read_size = sizeof(readbuf) 赋值,所以是读取消息。

binder_parse() 方法内部处理由 binder 驱动主动发出的、一系列 BR_ 开头的命令,包括上面提到过的 BR_TRANSACTION、BR_REPLY 等,简化后的代码如下:

int binder_parse(struct binder_state *bs, struct binder_io *bio,
uintptr_t ptr, size_t size, binder_handler func){
switch(cmd) {
case BR_TRANSACTION: {

res = func(bs, txn, &msg, &reply); //处理消息
//返回处理结果
inder_send_reply(bs, &reply, txn->data.ptr.buffer, res);

break;
}
case BR_REPLY: {…}
case BR_DEAD_BINDER: {…}

}
}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

img
img

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V:vip204888 备注Android获取(资料价值较高,非无偿)
img

最后

上面这些公司都是时下最受欢迎的互联网大厂,他们的职级、薪资、福利也都讲的差不多了,相信大家都是有梦想和野心的人,心里多少应该都有些想法。

也相信很多人也都在为即将到来的金九银十做准备,也有不少人的目标都是这些公司。

我这边有不少朋友都在这些厂工作,其中也有很多人担任过面试官,上面的资料也差不多都是从朋友那边打探来的。除了上面的信息,我这边还有这些大厂近年来的面试真题及解析,以及一些朋友出于兴趣和热爱一起整理的Android时下热门知识点的学习资料

部分文件:


部分文件:
[外链图片转存中…(img-gwUdZuox-1711555982474)]
[外链图片转存中…(img-vva7Yoin-1711555982474)]
[外链图片转存中…(img-IPxTEeIT-1711555982474)]

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值