Binder客户端和驱动端通信流程实例分析----以acquireWakeLock()函数为例 (一)

(本文适合对Binder框架具有基本了解,但缺乏感性认识的读者。为流畅阅读本文,读者还需要对Android Framework、Linux Kernel有一定的理解,并且手上最好有整套可编译的安卓6.0源代码,以便复现分析步骤。如有转载,请注明出自本博客。)


正文开始

下图是一张常见的Binder通信机制流程图:

现在我们从细节入手,以PowerManager内部类WakeLock提供的获取亮屏锁函数acquire()为例,分析客户端的上层Binder请求是如何一层一层地向下传递到驱动端。

为便于跟踪,需要创建一个demo程序,在demo程序中添加一个按钮,在按钮的onClick()函数中添加以下代码:

String TAG = "BinderDemo";
PowerManager.WakeLock wakeLock;
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "hello binder");
if (null != wakeLock) {
    Log.d(TAG, "before calling wakeLock.acquire()");
    wakeLock.acquire();          // 关键代码
    Log.d(TAG, "after calling wakeLock.acquire()");
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    wakeLock.release();
}
然后,编译demo程序并安装到手机中。

在上述代码中,首先获取电源管理PowerManager的一个WakeLock实例,然后通过该实例调用WakeLock类的acquire()函数。acquire()函数实际上会构造一个Binder请求,向下传递给Binder驱动设备,Binder驱动设备收到这个请求后,会根据这个请求所附带的Binder引用信息,找到对应的Binder服务端,将这个请求添加到Binder服务端的工作任务列表,此时客户端线程进入等待状态。在本例中,这个服务端就是PowerManagerService。当服务端完成这个请求后,会把结果传回Binder驱动,此时客户端线程收到返回数据,结束等待,一层一层地向上返回,直到退出acquire()函数。
上述过程涉及的代码很长很复杂,跨越了不同的进程,从app上层深入到底层kernel,又从底层kernel传递信号到服务端上层java代码,服务端上层代码处理完成后,返回给kernel层,然后又从kernel层返回到客户端app的上层,这一路峰回路转,机关暗藏,但呈现给开发人员的只有短短一句wakeLock.acquire(),这充分体现了Binder机制的巧妙设计。
接下来我们跟踪acquire()函数,看看

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值