Android-插件化

作者: 森屿暖茶 | 来源:发表于2021-02-19 16:43 被阅读0次

    插件化的意义和用处:

    app一般拥有者众多的功能模块,随着迭代,功能模块可能会越来越多,从而apk的体积会越来越大,但是新增的某些模块可能不是常用功能。这样就有着这么一个需求,用户在正常使用常用功能的时候,又能特殊需要使用部分频率较少功能的用户能够正常使用。插件化就是解决这个需求诞生的。我们把基础功能APP称为宿主APP,把摘除的功能模块APP称为插件app,用户在使用这些摘除功能的时候,下载插件apk,然后宿主app加载这个插件包,完成业务逻辑的闭合。插件化衍生(多开、换肤等)

    主要意义概括:业务模块解耦(解耦过后利于团队开发)、用户可按需下载、解决方法65535限制、插件和宿主是相对的,可以转换概念相互调用。

    市场上常用的插件开源框架

    插件化实现:我们需要对以下几个方面有相应的认知。

    ①Android的类加载机制。(我们需要将插件apk的dex文件中的class加载进入宿主中,一般我们会让宿主的dex 在前(这里跟热修复相反),因为能至少保证宿主没问题。请查看Android-类加载)

    ②Android的资源加载机制。(如何加载插件apk中的资源文件。请查看Android-资源加载)

    ③反射和动态代理。(因为插件apk的四大组件无法在宿主中注册,我们需要使用反射和动态代理的方法欺骗绕过(AMS)宿主app启动他们)

    ④Android的启动流程。(了解启动流程,寻找合适的Hook点)

    ⑤Binder相关知识。(四大组件之间的通信)

    以启动插件Activity为例:

    ①通过反射加载插件的dex文件生成的element和宿主的element合并,宿主的在前,参考热修复。然后赋值设置回宿主的elements。目的:这样宿主的classloader就能加载插件的class了。(参考Android-类加载)

    ②我们直接启动插件的activity是无法启动的,因为(熟悉Acitvity的启动流程AMS,知道activity启动需要通过AMS检查(跨进程)后才能启动activity),所以插件的activity是无法通过AMS检测的,所以我们需要在宿主中已注册好一个ProxyActivity(供插件activity使用),在启动插件的activity时我们hook AMS检测的地方,把intent替换为ProxyActivity,这样就能够通过AMS检测,继续后续的activity启动流程。(不同API 版本源码不一样  需要兼容)

    ③由于我们在AMS检测的地方hook 改变了intent,所以如果不做任何操作的话我们将会启动插件的ProxyActivity。所以我们要在通过AMS检测过后,启动activity之前把intent信息改回来。由于activity启动是通过handler msg方式启动的,所以我们只要更改msg中intent的信息即可,更改intent信息过后,再继续启动activity,即可启动插件activity。(不同API 版本源码不一样  需要兼容)

    流程图

    总结:系统启动一个Activity 需要在AMS(跨进程)中检测清单文件(manifest)中是否有注册该activity,通过检测才能正常进入后续的activity的启动流程(通过handler msg 启动)。所以我们首先,需要能够加载启动类,然后在启动插件activity 经历AMS检测时,通过更改intent信息,把intent改为已注册的proxyActivity来通过AMS检测,在通过检测过后需要把intent信息改回(因为我们在AMS检测的时候intent信息被我们改成插件的了)我们需要启动的插件activity。最后成功启动未注册的插件activity,可以理解为狸猫换太子的思路···。

    相关文章

      网友评论

        本文标题:Android-插件化

        本文链接:https://www.haomeiwen.com/subject/hrslaktx.html