Android插件化之Hook底层原理

最近插件化比较流行,同时也涉及到很多底层源码,内容较多,本文将会将最精华的部分挑出来讲,尽可能把插件化吃下去,将按照下面三个模块来分析,:

  1. 插件化诞生背景
  2. Hook是什么
  3. 底层实现原理

插件化诞生背景

什么是插件化?

我们先来看看下面的场景:

1、如果要做功能丰富的apk,在里面,我们能玩到各种各样的游戏(如一个游戏平台),如果要将所有的游戏代码都预先写到一个apk里面,用户的下载及安装的时间成本则非常高,用户体验无疑十分糟糕。(结合znjc谈)

2、现在我们开发的apk功能需要持续迭代更新,更新频率比较高,是否意味着要让用户高频地下载安装来更新apk?有没有什么好的办法,能解决这个问题?

为了能同时解决上面两个痛点,插件化就出来了:

插件化就是能将一个apk的复杂业务按功能分成多个模块,每个模块作为一个单独的apk,通过hook机制(后面详解)让用户按需下载安装,在需要更新时,能够实现免安装更新的技术

(此处补个对比图)

Hook是什么?

从上面的对插件化的解释,可知实现插件化的关键技术就是Hook,所以问题又来了,什么是Hook?

我们先来想一下,解决上面两个问题的方法:

上面两个问题翻译一下就是怎么免去用户主动下载安装这个过程,来到达在安卓系统中运行或更新我们的“业务功能”,我们知道由于安卓系统的设计和权限的限制,任何app都必须先安装之后才能运行业务工能,那有什么好办法?

1. 热更新

热更新其实就是在代码中的各个位置设置一个入口,在需要更新的时候找到入口处,进行对应更新,它能在apk的各个位置进行更新,但缺点也非常明显:

热更新因为调用到大量android底层代码,又因为android本身开源,各大厂商都可能修改底层相关代码,兼容性困难,所以热更新技术开发维护难度巨大,人力和时间投入不菲,所以现在能用其他技术的,都不会用它

2. Hook

那热更新不行,还能怎么办?这时候Hook就出场了,既然明着来不行,我们就“偷着来”;你android系统即然一定要安装,那我就“欺骗”你一下,让你误以为安装了,这就是Hook:

一种函数拦截技术,在进程间正常通信的时候进行拦截,将通信过程中传递的结果替换为我们想要的结果,实现欺上瞒下,从而达到免安装运行的目的

那现在知道了hook是一门“欺骗”的技术,那它要去骗谁,才能达到免安装apk的目的?

这其中最关键的是对AMS(Activity Manage Service)和PMS(Package Manage Service)以及Handler的hook。AMS负责管理Android中Activity、 Service、Content Provider、Broadcast四大组件的生命周期以及各种调度工作,我们hook它可以实现对插件四大组件的管理及调度;

PMS负责管理系统中安装的所有App,我们hook它是为了让插件以为自己已经被安装;

Handler是系统向插件传递消息的一个桥梁,我们hook它则是为了把系统发向宿主的消息转发给插件。


(图二)

底层实现原理

由于篇幅巨大,所以主要讲解图二中Hook是如何“欺骗AMS”,来达到启动一个我们想要的activity(界面)的目的

由于涉及AMS,而AMS的底层实现是基于Binder的,所以会根据以下思路讲解:


(图三)

1. Binder基本原理

Binder分为Client和Server两个进程

注意,Client和Server是相对的。谁发消息,谁就是Client,谁接收消息,谁就是Server
举个例子,进程A和进程B之间使用Binder通信,进程A发消息给进程B,那么这时候A是Binder Client,
B是Binder Server;进程B发消息给进程A,那么这时候B是Binder Client,A是Binder Server
其实,这么说虽然简单,但是不太严谨,我们先这么理解。
复制代码

(Binder底层原理图)

总结来说:就是类似于代理

Guess you like

Origin juejin.im/post/7035773099303764004