史上最强Android保活思路:深入剖析腾讯TIM的进程永生技术(6)
2023-04-30 来源:飞速影视
问题2:startService()的callingPid怎么可能等于0?
5.3.1)分析callingPid=0:
为什么说上面是意外的一幕呢?这需要对binder底层原理有一定深入理解,才能看出一些端倪,那就是此处callingPid=0是不合理逻辑的。很多人可能不太理解为何就不合乎逻辑, 这要从Binder原理说起, startService()这个Binder call是属于同步binder调用, 对于binder调用过程,只有异步Binder调用的情况下callingPid=0才会为空, 因为不需要reply应答数据给发送binder请求的那一端。 但如果是同步的,则必须要给出callingPid,否则无法将应答数据回传给发送方。 这是由Binder Driver所决定的,见如下Binder Driver核心代码。
(1) Binder发起端:根据当前ONE_WAY来决定是否设置from线程
binder_transaction(...) {... if(!reply && !(tr->flags & TF_ONE_WAY)) t->from = thread; else t->from = NULL; } ...}
(2) Binder接收端: 根据from线程是否为空, 来决定sender_pid是否为0. 这便是Java层所说的callingPid
binder_thread_read(...) {... t_from = binder_get_txn_from(t); if(t_from) { structtask_struct *sender = t_from->proc->tsk; tr.sender_pid = task_tgid_nr_ns(sender, task_active_pid_ns(current)); } else{ tr.sender_pid = 0; } ...}
上述代码表明: 同步的Binder调用的情况下则callingPid必定不等于0。
下面告诉大家如何看一个Binder调用是否同步, 如下图最后一个参数代表的是FLAG_ONEWAY值,等于0则代表的是同步, 等于1则代表的是异步。
本站仅为学习交流之用,所有视频和图片均来自互联网收集而来,版权归原创者所有,本网站只提供web页面服务,并不提供资源存储,也不参与录制、上传
若本站收录的节目无意侵犯了贵司版权,请发邮件(我们会在3个工作日内删除侵权内容,谢谢。)
www.fs94.org-飞速影视 粤ICP备74369512号