插件化的意义和用处:
app一般拥有者众多的功能???,随着迭代,功能??榭赡芑嵩嚼丛蕉啵佣鴄pk的体积会越来越大,但是新增的某些??榭赡懿皇浅S霉δ堋U庋陀凶耪饷匆桓鲂枨?,用户在正常使用常用功能的时候,又能特殊需要使用部分频率较少功能的用户能够正常使用。插件化就是解决这个需求诞生的。我们把基础功能APP称为宿主APP,把摘除的功能??锳PP称为插件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,可以理解为狸猫换太子的思路···。