Atlas框架介绍集成(一)
Atlas是什么?
Atlas是一个Android客户端容器框架,主要提供了组件化、动态性、解耦化的支持。支持在编码期、Apk运行期以及后续运维修复期的各种问题。
- 在工程期,实现工程独立开发,调试功能,工程模块的独立。
- 在运行期间,实现完整的组件生命周期映射,类隔离等机制。
- 在运维期间,提供快速增量的更新修复功能,快速升级。
Atlas是工程期和运行期共同起作用的框架,它尽量将一些工作放在工程期,这样保证运行期的简单、稳定。
Atlas组件化实现
上图是手机淘宝的apk,第一层目录上与标准的apk是完全一样的。在App会有很多的so文件,每个送文件如果解开来看它的结构类似于完整的apk,但本身不能独立运行,它跟很多傻简化的差别是在运行期,它是运行在整个容器里,每一个组件都是独立的Bundle。
从模块来划分,手淘APK可以分为两层,上层是经过拆分的业务Bundle,扫码、评价、详情,各个业务之间可以进行功能的调用,可以通过路由调度到其他业务方。下层是共享的底层中间件,向业务方开放各种能力,如网络库、图片库等,会在容器里进行统一地把控,这样做的好处是包做到尽可能小,第二是性能佳。
这一块是Atlas的整体设计,分为五层:
第一层称之为Hack层,包括OS Hack toolkit & verifier,这里对系统能力做一些扩展,然后做一些安全校验。
第二层是Bundle Framework,就是的容器基础框架,提供Bundle管理、加载、生命周期、安全等一些最基本的能力。
第三层是运行期管理层,包括清单,会把所有的Bundle和它们的能力列在一个清单上,在调用时方便查找;另外是版本管理,会对所有Bundle的版本进行管理;再就是代理,这里就是和业界一些插件化框架机制类似的地方,会代理系统的运行环境,让Bundle运行在的容器框架上;然后还有调试和监控工具,是为了方便工程期开发调试。
第四层是业务层了,这里向业务方暴露了一些接口,如框架生命周期、配置文件、工具库等等。
最上面一层是应用接入层,就是的业务代码了。
所以Atlas作为一个框架提供了相对完整的能力,业务层的开发可以在框架生命周期的各个环节做一些自定义的动作,也可以自由的调用系统、框架,乃至其它组件释放的能力
组件化技术细节
关于Bundle的生命周期会提供细粒度的节点,比如下面是一个Bundle从加载到运行的周期:
- startInstall:开始加载。这个时候框架会做一些拷贝文件、释放lib、加载Bundle的事情;
- Installed:加载完毕。这时框架会注入资源路径,创建class loader;
- resolved:解析完毕,框架会检查组件配置是否合法,是否能被解析;
- active:运行组件,即开始运行组件Bundle;
- started:运行成功。
组件化涉及到的第一个问题是Manifest处理,一个是因为来源很多,有宿主Manifest、Aar Manifest以及组件Manifest,另外不同组件的Manifest经常发生变化,要求灵活地去处理。这里的做法是在工程期将所有的Manifest进行Merge操作,这里需要注意的是Bundle的依赖单独Merge,因为这里涉及到依赖仲裁的问题。最后解析各个Bundle的Merge Manifest,得到整包的BundleInfoList,就是上面提到的Bundle信息清单。
第二个是类加载,这里利用Delegate ClassLoader来动态加载组件的类。Delegate ClassLoader先查找宿主Bundle的PathClassLoader,然后根据前面的BundleList找到对应的BundleClassLoader.
第三个是资源,会用自己的DelegeteResources替换掉系统的resource,Bundle的资源会逐个在安装的时候添加到AssertPath,由于添加Bundle的顺序非固定,不分区会导致资源查找错乱。
另外,Dalvik和ART上的资源查找过程顺序是不一样的,加上小米等系统会重写自己的resources,所以会适配不同的机型,往后追加AssetsPath或者往前追加,系统AssetManager是个单例,默认往后追加,如果往前追加,则需要重新创建AssetsManager对象,同样主dex动态部署的时候要达到替换原有resource的目的,必须保证插入顺序与查找顺序一致。
还有需要注意的是,每次更新resourceTable的时候,必须保证apkresource,runtime的系统resource,例如webview,bundle resource都已经添加成功,而且唯一,顺序正确。
不同Bundle的资源可能发生命名冲突,是用了一种相对来说简单的方法,将各自的Bundle分配成不同的ID,保证所有的业务资源不会产生冲突,尽量将问题放到工程期解决。在很多代码里,通过反射来调用整个资源,在5.0以上的系统是没有问题的,它只找第一个,对业务代码而言,原来是怎么写的,今天还是怎么去写。
关于组件化性能这一部分,引入了按需加载,因为手淘APK有70多个Bundle,每个用户真正用的时候只需要5或10个,所以不需要加载所有的Bundle。Bundle之间进行隔离,通过Android四大原生组件进行交互,这样Bundle之间可以比较好的解耦。所有调用的入口都是基于BundleInfolist去做的,根据这个清单信息,得到组件所在Bundle,如果需要加载,就进行install、dexopt等操作。
另外,对于解决组件依赖问题,定义了两种新的组件格式Awb(业务Bundle)和solib(so库),前者与AAR一致,不过不添加本地lib,在构建的时候做依赖仲裁区分,后者是Native so库的依赖。Awb其实就是AAR,只是后缀修改了,如果你的包放在宿主Bundle就用AAR,如果是组件Bundle就用Awb。
对于业务Bundle的依赖,在构建期会将宿主Bundle和业务Bundle及其依赖分别打包,然后按照最短路径、第一声明原则进行树状仲裁,得到每个Bundle需要的依赖,在打包的时候会将依赖库放到各自的Bundle里去。
最后是APK构建,对它做了比较大的调整。上面的图中,其实左边这一部分是一个标准的APK的构建过程,包括处理,编译,到签名的过程。这个不同的地方是多了Awb需要特殊处理,其中Awb的资源根据宿主的resource.ap_和包内资源构建,R文件由Bundle R资源和宿主R资源合并而来,然后对Aapt进行了修改,对每个awb分配不同的packageId,然后进行统一混淆,生产各个AWB的Dex,打包为APK,签名之后复制到libs,改名为so文件,然后合并到taobao APK. 这就是组件化的整个过程。
Atlas动态化
在一个容器框架内,组件化和动态化是相辅相成的,组件只是解决了解耦的问题,但如果想要随时发包,就必须让容器框架具备动态化能力。在完成了Atlas的组件化之后,做了动态化的支持。动态化的好处一个是包的大小缩减,可以将一些包在运行后下载到应用中,另一个是具备动态发版和修复能力。
增量动态化方案
Atlas提供了动态部署的能力,主要目标是动态业务发布,以及问题修复。它基于手淘自研差量算法,主Bundle基于ClassLoader机制,业务Bundle基于差量merge,支持全业务类型。
另外,Atlas也支持Andfix作为插件使用,目标是快速故障修复,它的原理基于Native hook,主要做方法的修改,在实际中可以两个一起用。在工程构建期适配之后,可以做到一套代码两套方案通用。
自研动态部署功能实现原理,首先,对于Dex Patch的生成,通过修改Dex的字节码实现,将Dex文件转为Smali,对其中的ClassDef和ClassDataMethod结构体进行分析,可以实现删除、新增、修改类,然后通过Diff处理得到差量文件,再通过Merge处理即生成补丁。
其次是整个资源Patch的生成,分为两块,一个是业务Bundle,本来是一个不断加载的过程,它实现起来会比较简单,通过Md5 diff/BSDiff即可得到。对于主Bundle,因为安卓本身有一个限制,所有的资源必须得在base包里,新增一个资源是不生效的。所以一个做法是在打包的时候预留很多空资源。另外更新已有的资源则通过资源覆盖来完成。
最后,如果新加业务的话,会新加Activity,的做法首先在Manifest预埋一个StubActivity,然后在Instrumentation.execStartActivity()阶段进行替换,同时配合Intent setFlag模拟Activity launch mode并继续startActivity,接着System_server进程进行处理,更新ActivityStack,创建binder,并通知ActivityThread进行实例创建,最后在ActivityThread的handler里面进行拦截,更新ActivityInfo等信息,创建目标Activity。
另外在工程实践上,因为补丁的生成会涉及到Dex和资源的基线,会在部署的时候,每次发布APK包同步发布AP(基线包)到Maven,AP基线包里是所有影响基线的文件,第一是安卓APK,第二是Mapping.txt,最后是Dependency.txt,这样的话整个构建的速度会非常的快。
所以这种方式,版本的升级是不同的方式。比如今天手淘的详情要更新,会发布版本,这个版本可能不是到应用市场的版本,而是一个Patch包。业务版本的动态部署,是同步的,5.3.0到5.3.1到5.3.2,这样一个好处是只要容器版本没有升级,只要有需求,patch就可以一直升级,而且是无感知的差量升级。
Atlas框架介绍集成(一)的更多相关文章
- CXF框架介绍及Spring集成
1.CXF框架概念介绍 Apache CXF 是一个开源的 WebService 框架,CXF可以用来构建和开发 WebService,这些服务可以支持多种协议,比如:SOAP.POST/HTTP.H ...
- [连载]《C#通讯(串口和网络)框架的设计与实现》-1.通讯框架介绍
[连载]<C#通讯(串口和网络)框架的设计与实现>- 0.前言 目 录 第一章 通讯框架介绍... 2 1.1 通讯的本质... 2 1 ...
- .Net下几个服务框架介绍
简介 在公司的服务多了以后,为了调用上的方便,同时为了以后的服务治理,一般都会使用一些服务框架,这里主要介绍我知道的几个服务框架,简析一下这些服务框架的基本概念. 可投入生产环境使用的 以下两个服务框 ...
- Selenium自动化测试框架介绍
Selenium自动化测试框架介绍 1.测试架构作用 a.可维护性 b.提高编写脚本效率 c.提高脚本的可读性 2.框架的几大要素: Driver管理,脚本,数据,元素对象,LOG,报告,运行机制,失 ...
- [翻译]Spring框架参考文档(V4.3.3)-第二章Spring框架介绍 2.1 2.2 翻译--2.3待继续
英文链接:http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/overview.ht ...
- 挑战EXT——QUI框架介绍与下载
挑战EXT——QUI框架介绍与下载 为庆祝新版QUI问世特写此文: 提起EXTJS的大名,恐怕WEB开发界无人不晓吧.EXTJS框架发展到现在,已经非常成熟和全面了.它的组件库尤其是DataGrid组 ...
- android常用http框架介绍
测试数据 1.HttpURLConnection:在Android 2.2版本之前,HttpClient拥有较少的bug,因此使用它是最好的选择.而在Android 2.3版本及以后,HttpURLC ...
- iOS框架介绍
iOS框架介绍 Cocoa Touch GameKit 实现对游戏中心的支持,让用户能够在线共享他们的游戏相关的信息 iOS设备之间蓝牙数据传输 从iOS7开始过期 局域网游 ...
- LindDotNetCore~框架介绍及特色功能(有点springboot的意思)
LindDotNetCore模块介绍 大叔博客 LindDotNetCore相关模块介绍 [x] 全局都是依赖DI [x] 消息队列 [x] NoSql [x] Caching [x] 仓储 [x] ...
随机推荐
- JavaWeb(八)JQuery
jQuery 市场用得比较多两个框架: jQuery 比较适合做一些互联网 的应用(12306.com,蘑菇街,美丽说,聚美) extjs 比较适合做后台管理系统(电商(订单管理),银行,电信) 核心 ...
- mysql排序
MySQL里desc和asc的意思 desc是descend 降序意思 asc 是ascend 升序意思 sql = "select 表内容名 from 数据库 ...
- Java - 9个处理异常的最佳准则
其实工作这么久了一直都没搞清楚到底如何来处理异常,偶然看到一篇外文感觉还不错,便把它翻译了下来,原文链接位于本文末尾处. 在java中处理异常并不是一件简单的事,不止初学者觉得它难以理解甚至连有经验的 ...
- Java基础---网络编程
第一讲 概述 1.网络模型:OSI参考模型和TCP/IP参考模型 图示: 一般来说开发处于传输层和网际层,应用层为:FTP和HTTP协议等,传输层为:UDP和TCP等,网际层为:IP. 通常用 ...
- JAVA 文件编译执行与虚拟机(JVM)简单介绍
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytpo3 java程序的内存分配 JAVA 文件编译执行与虚拟机(JVM)介绍 ...
- [ASP.NET MVC]笔记(三) 成员资格、授权和安全性
阻止CSRF(跨站请求伪造) ASP.NET MVC提供了一个阻止CSRF攻击的好方法 在每个提交的表单中包含 @using (Html.BeginForm("Index", &q ...
- spring boot认识
Spring Boot的好处: 1.配置简化 2.配合各种starter使用,基本上可以做到自动化配置 3.上手速度快 4.提供运行时的应用监控 运用IDEA创建spring boot项目请查看: h ...
- 查看linux网卡硬件名称
查看linux网卡硬件名称 lspci | grep -i ether
- css3 如何实现圆边框的渐变
使用 css 实现下面效果: 把效果分解. 代码一: <style> .helper1 { height: 40px; padding: 15px; background: -webkit ...
- 【Beta】阶段 第一次Daily Scrum Meeting
每日任务 1.本次会议为第一次 Meeting会议: 2.本次会议在周一下午16:40,课间休息时间在禹州楼召开,召开本次会议为10分钟. 一.今日站立式会议照片 二.每个人的工作 (有work it ...