完成日期:2020年7月8日
版本:V1.0
作者:龚va
邮箱:shmily__vivi@163.com
目录
第一章 总体思路
第二章 整体架构
2.1 技术架构
2.2 组件化
第三章 技术能力
3.1 NATIVE开发
3.1.1 统一架构
3.1.2 开发语言
3.1.3 开发工具
3.1.4 构建工具
3.1.5 代码分支管理
3.1.6 代码检查
3.1.7 编码规范
3.2 混合开发
3.3 系统测试
3.3.1 用例评审
3.3.2 冒烟测试
3.3.3 功能测试
3.3.4 自动化测试
3.3.5 性能测试
3.3.6 安全测试
3.3.7 兼容性测试
3.4 运维与发布
3.4.1 内网办公
3.4.2 发布部署
3.4.3 服务监控
3.5 热修复
3.6 日志收集与统计
第四章 流程管理与质量体系
4.1 项目流程管理
4.2 安全管理
4.2.1 服务器物理安全
4.2.2 网络安全
4.2.3 应用安全
4.2.4 数据安全
4.3 文档管理
第五章 落实步骤
第一章 总体思路
程序总体架构满足“高内聚、低耦合”的建设思路,架构模式采用MVVM,利用组件化思维解除模块间不必要的依赖关系,组件可独立开发、发布与管理,提高模块开发的独立性,提升协作效率。
利用持续集成工具提升发布效率,增加发布流程降低发布出错率。
利用监控与统计工具及时发现服务器运行状态异常、App运行异常与用户行为收集,及时进行问题溯源,重要问题可使用热修复技术及时修复。
测试类型的完整引入,搭建全生命周期项目管理流程体系,清楚定义阶段交付物,同时搭建从服务端到App端完整的安全体系,以提高送测与发布程序质量。
统一开发工具与开发环境,统一编码规范、代码检查规范与分支管理规范,持续维持健康的团队协作。
第二章 整体架构
2.1 技术架构
整体架构模式采用MVVM,逻辑处理从业务层转移至模型层与数据层,减小Controller的压力与冗余,也更便于二次维护,数据仓库维护本地与远端数据源,程序使用组件加业务功能组装的方式进行构建,同时提供线上用户行为收集、程序运行错误日志上报及热修复功能。
MVVM架构
MVVM是Model-View-ViewModel的简写,是将其中View的状态和行为抽象化,将视图UI和业务逻辑分开。具有数据驱动、低耦合、可复用性、团队协作等优点。
Retrofit+OKHttp3:http(s)通信
Retrofit是Square公司开发的一个类型安全的Java和Android 的REST客户端库,配合OKHttp完成是对网络请求的封装,可以处理各种类型的请求并具有众多特性,使用简单,运行稳定。
RxJava2/RxAndroid
一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库。
Glide图片加载
Glide是一款由Bump Technologies开发的图片加载框架,可以在Android平台上以极度简单的方式加载和展示图片,支持Gif,支持缓存。
EventBus:通信总线
一种用于Android的事件发布-订阅总线,简化了应用程序内各个组件之间进行通信的复杂度,尤其是碎片之间进行通信的问题,可以避免由于使用广播通信而带来的诸多不便。
AliPush:推送服务
集成阿里云推送,完成App的推送服务功能,根据业务场景可选。
ARouter:页面路由
阿里开源的一款android路由框架。通过路由进行界面跳转,区别于Intent的显隐式跳转。在模块化的项目中,友好的解决了因模块互相依赖冲突,而界面互相跳转不了的问题,使用ARouter进行跳转,两个模块互相不依赖,也可以相互跳转。
Tinker:热修复
Tinker是微信官方的Android热补丁解决方案,它支持动态下发代码、So库以及资源,原理基于dex分包机制,让应用能够在不需要重新安装的情况下实现更新。
Walle:多渠道打包
瓦力通过在Apk中的APK Signature Block区块添加自定义的渠道信息来生成渠道包,从而提高了渠道包生成效率。
JsBridge:与H5交互
Js与Native之间进行通信的桥梁, 可实现H5和Native的双向通信,在H5和Native之间搭建一个桥梁(Bridge),给两端留好更友好、更合理的接口。
Ali/WeiXin Pay:支付
支付业务集成:微信支付、支付宝支付,可对接官方SDK,也可对接工行、中金等三方平台,根据业务场景可选。
Umeng:分享与统计
友盟社会化分享集成框架,还可以附带其友盟强大的统计功能,提供分享结果数据,根据业务场景可选。
Gson:数据解析与格式化
Gson是Google提供的用来在Java对象和Json数据之间进行映射的Java类库,快速高效、代码量少、且面向对象。
Bugly:日志收集
在线的错误日志收集,便于稳定性分析。
BaiduSDKs:百度(地图/语音/人脸/文字识别)
地图SDK:该套 SDK开发适用于Android系统移动设备的地图应用,通过调用地图SDK接口,可以访问百度地图服务和数据,构建功能丰富、交互性强的地图类应用程序,根据业务场景可选。
语音SDK:百度语音识别服务,语音识别可将语音识别为文字,适用于手机应用语音交互、语音内容分析、智能硬件、呼叫中心智能客服等多种场景,根据业务场景可选。
人脸SDK:百度人脸识别SDK,用于对活体人脸的识别,人脸比对,人脸搜索等场景下的应用。
文字识别:百度文字识别(OCR)服务,用于对如身份证件,驾照等纸质文字证件文字识别,根据业务场景可选。
版本说明
最低兼容版本Android4.4(据2020年4月谷歌统计,4.4以下版本手机的市场占有率不到2%)
编译版本Android9.0,目标运行版本Android9.0(目前市场占比最高的稳定版本)
2.2 组件化
组件化是将复杂的功能模块的逻辑、数据、UI等元素积木式的进行拆分、重组的过程,形成单个可以独立开发和测试的组件。
组件化可以极大程度的提高协作效率,将不同模块间的开发完全解耦,配合路由框架,做到不同模块间的代码管理、编译、测试、发布等独立,可通过Maven仓库进行管理,模块间的边界清晰,也为问题溯源提供了足够的思路与历史记录。
单个组件的构建思路应遵循逻辑能力与UI展示解耦,当UI展示不满足组件使用者的要求时,允许只使用组件能力,以此来满足复杂多变不可控的众多业务场景。
Core核心组件
提供基于java、android语言级的工具方法集合。如:加解密、时间工具、数字运算、进程/线程工具、键盘、屏幕、网络监听工具等。
基础功能组件
提供Base的Application、Activity、Fragment、Custom View、Manager、Loading Controller、Configuration、Lifecycle等的基准类库;
同时提供功能插件,如:网络请求Retrofit、Android动画、IO相关操作、总线通信EventBus、图片加载glide、图片/文件加载库、权限管理等。
基础业务组件
提供通用又可选的一些能力的封装,如:地图能力、扫码能力、推送能力、数据库管理能力、分享能力、热修复、人脸/图像识别、一键打包、语音能力、统计能力、图表绘制能力等。
常规业务组件
这一层和业务功能挂钩,通常会有一个对业务功能的分析和提炼的过程,将具有相同特性的功能封装成常规业务组件,此类组件通常会持续的新增和维护。如:登录/注册、App版本更新、广告、订单与支付、引导、内嵌H5等。
App壳工程
主App工程,选择性的对各类组件进行特性定义或组装,结合非组件功能,构建完整的Application。
第三章 技术能力
3.1 Native开发
无论是同一个线下团队还是多地协作的多团队,都需要统一的一套技术栈,加上规范与流程的约束,即可避免很多环境差异、认知差异、习惯差异、能力水平差异等带来的问题。
3.1.1 统一架构
开发语言可采用Java、Kotlin混用模式,框架级代码为了适应更多技术层次的团队成员建议采用Java编写,业务功能模块的开发允许使用Java或Kotlin中任意一种。
3.1.3 开发工具
开发工具使用Android Studio,参考版本3.6.1,并使用相同的Code Template,规范团队的注释、换行等规范。
3.1.4 构建工具
采用Gradle作为自动化构建工具,工程变量的配置、CPU架构配置、编译配置、Maven上传、三方库版本管理等均在Gradle中统一配置,并通过自定义Task来完成特定的项目常用任务,如:Clean Project,Build Release,Make Channel等。
3.1.5 代码分支管理
采用Git统一管理项目代码,可在团队均可以访问且安全的网络环境中搭建一套GitLab,并遵循团队共用的分支管理规范,参考:
3.1.6 代码检查
形成定期的Code Review制度,并在Review中检查代码的完整性、一致性、健壮性、重用性、扩展性、性能、安全性、注释等。
3.1.7 编码规范
团队采用统一的编码,保证代码风格一致。(参考文档不在此处另附)
3.2 混合开发
针对Native与H5混合开发的情况,需要提供一套完整且统一的Native与JavaScript的通信规范,同时Native需要提供Js可唤起和跳转的Scheme路由地址。
通常可以分为Js->Native的数据类与动作类Handler和Native->Js的数据类与动作类Handler,传输数据类型与格式根据业务自定义,Handler Name参考:
Js->Native数据类:com.company_name.native_echo.data
Js->Native动作类:com.company_name.native_echo.action
Native-> Js数据类:com.company_name.javascript_echo.data
Native-> Js动作类:com.company_name.javascript_echo.action
3.3 系统测试
测试的设计与执行过程需要完整有序,对产品性能、质量、安全、兼容性要做到全方位兼并,通知借助工具与测试技术,提高效率。
3.3.1 用例评审
测试用例的设计需要内部评审与外部评审,内部评审以校验功能覆盖率,外部评审以校验逻辑正确性,管理工具可使用TestLink。
3.3.2 冒烟测试
冒烟测试是开发过程中的一种快速的基本功能的验证策略,是对软件基本功能进行确认验证的手段与过程。
开发版本达到送测标准的前提是冒烟测试通过,测试团队负责冒烟测试用例的设计与维护,研发团队负责参与评审与执行,以保证送测的主功能与流程通畅,若冒烟测试不通过,测试团队有权将送测流程打回。
3.3.3 功能测试
功能测试是根据产品设计、交互体验、数据逻辑等要求,对产品各功能进行验证,以检查产品达到既定的要求,是最常见的且必要的测试过程。参考:
测试用例完整执行
测试问题完整回归
边界值
覆盖率
不允许Reopen
测试报告
3.3.4 自动化测试
对系统中很重要且不经常变更设计的功能进行自动化测试,以提高测试效率与程序稳定性,如:注册/登录、版本更新等。
3.3.5 性能测试
使用Android Studio的Profile工具进行性能测试,关注的性能问题包括但不仅限:
应用耗电量过大
设备发热
程序启动较慢
CPU告警/内存泄漏
页面卡顿、帧率低
设定性能目标,根据性能测试结果持续进行程序优化。
3.3.6 安全测试
安全测试通常是一个很大的课题,因为Android系统开源,因此在Android领域中需要做的安全检查项较多,根据项目与客户的安全等级不同,可选择性的执行以下的部分或全部安全检查项。
程序安全
安装包签名和证书
检测 App安装包是否正确签名,通过签名,可以检测出安装包在签名后是否被修改过。
数据可备份
AndroidMainfest.xml 文件中的 allowBackup 属性值默认为 true。当该属性没有显式设置为 false 时,攻击者可通过adb backup和adb restore 对 App 的应用数据进行备份和恢复,从而可能获取明文存储的用户敏感信息。
程序保护
App未提供防反编译的手段,则可能面临被反编译的风险。
Debug模式
AndroidManifest.xml中的 android:debuggable="true" 标记如果开启,可被 Java 调试工具例如 jdb 进行调试,获取和篡改用户敏感信息,甚至分析并且修改代码实现的业务逻辑。
完整性校验
程序如果没有自校验机制,攻击者可能会通过篡改客户端程序,植入木马以窃取手机用户的隐私信息。
组件安全
Content Provider
若没有对Content Provider 组件的访问进行权限控制和对访问的目标文件的Content Query Uri 进行有效判断,则openFile()接口可进行文件目录遍历以访问任意可读文件。
WebView代码执行检测
Android系统通过addJavascriptInterface 方法注册可供 JavaScript 调用的 Java 对象,以用于增强 JavaScript 的功能,但是系统并没有对注册Java类的方法调用进行限制,攻击者可以利用反射机制调用未注册的其它任何Java类,最终导致JavaScript能力的无限增强,利用该漏洞可以利用Js执行客户端任意代码。
WebView校验证书
调用了android/webkit/SslErrorHandler类的 proceed方法,可能导致WebView忽略校验证书的步骤。
WebView密码明文保存
在使用WebView的过程中忽略了 WebView setSavePasswor,当用户选择保存在 WebView 中输入的用户名和密码,则会被明文保存到应用数据databases/webview.db中。如果手机被 root就可以获取明文保存的密码,造成用户的个人敏感数据泄露。
敏感信息安全
敏感文件与字符检查
检查App私有目录下的文件是否存在敏感信息泄露的情况。
程序目录权限检查
检查App私有目录下的文件权限是否设置正确,非root 账户是否可以读、写、执行私有目录下的文件。
LogCat日志检查
检查是否关闭了调试日志的输出。
密码软键盘安全
键盘劫持检查
检查App在密码等输入框是否使用自定义软键盘。Android应用中的输入框默认使用系统软键盘,手机安装木马后,木马可以通过替换 系统软键盘,记录应用的密码。
安全策略
密码复杂度
检查App的密码复杂度要求设计是否过于简单。
会话安全
测试App在一定时间内无操作后,是否会使会话超时并要求重新登录。
界面切换保护
检查App在切换到后台或其他应用时,是否能恰当响应(如清除表单或退出会话),防止用户敏感信息泄露。
用户敏感信息泄露
检查App是否存在敏感信息泄露。
登录安全
根据业务需求检查程序是否需要单点登录。
安全退出
验证App在用户退出登录状态时是否会和服务器进行通信以保证退出的及时性。
验证码安全
验证移动客户端使用的验证码的安全性,如图形验证码是否轻易被机器识别。
通信安全
通信加密检测
验证App和服务器之间的通信是否使用加密信道。
关键数据加密检测
验证通信过程中能否对关键数据进行篡改。
SSL证书有效性检测
验证App和服务器之间是否存在双向验证的机制,同时确认此机制是否完善,服务器是否以白名单的方式对发包者的身份进行验证。
访问控制
测试App访问的 URL 是否仅能由手机移动客户端访问。是否可以绕过登录限制直接访问登录后才能访问的页面,对需要二次验证的页 面(如私密问题验证),能否绕过验证。
进程安全
内存访问与修改检测
通过对App内存的访问,有可能会得到保存在内存中的敏感信息(如登录密码,帐号等)。测试App内存中是否存在的敏感信息(卡号、明文密码等)。
本地端口开放检测
使用domain的socket来进行本地 IPC 或者远程网络通信,这些暴露的socket代表了潜在的本地或远程攻击。
外部加载Dex安全风险
类加载器DexClassLoade可以加载外置目录的DEX文件,如果没有对外部所加载的DEX文件做完整性校验,则可能会被注入恶意代码。
业务安全
存储型XSS漏洞
Web应用未对用户提交的数据做充分的检查过滤,允许用户在提交的数据中掺入 HTML 代码(最主要的是“>”、“<”)并将未经转义的恶意代码输出到第三方用户的浏览器解释执行,从而导致 XSS 漏洞。
短信炸弹
务器端若没有对短信发送接口做限制,则可能导致短信炸弹漏洞。
3.3.7 兼容性测试
团队应该配备主流品牌的测试机型,但由于Android机型众多,所以通常还会采用第三方云平台辅助进行兼容性测试,如:testin。
测试范围包括:可安装、安装耗时、可卸载、可启动、启动耗时、monkey测试等。
3.4 运维与发布
3.4.1 内网办公
文档管理:SVN
代码管理:Gitlab
项目管理(含BUG管理):Jira
知识库管理:Confluence
接口管理:Yapi
测试用例管理:Testlink
3.4.2 发布部署
配置中心:Apollo
持续集成(自动化构建):Jenkins
发布流程:发布申请->发布准备->Check List->发布执行->发布验证
3.4.3 服务监控
利用后端与运维技术,以实现及时的服务监控,监控范围与技术参考:
服务器监控(包括硬件资源、数据库、缓存、流量等):Zabbix、Prometheus
应用监控:Springboot Admin
中间件管理:Rabbitmq admin、Kafka admin、ES Kibana
链路监控:APM SkyWalking
日志跟踪:ELK(Elasticsearch, Logstash, Kibana)
3.5 热修复
由于Android机型碎片化,线上环境复杂多样化,APP发布后总会遇到一些开发环境无法测试覆盖的缺陷:崩溃、数据错误、链接跳转失败、商品无法交易等。传统处理方式需要发现问题、定位问题、修复问题、发布新的版本。这种方式一方面会让APP频繁更新,用户体验不好,另外App Store也有一些审核的周期,修复问题时间成本高,最终导致客户流失、资金损失等后果,因此热修复技术应运而生。
Android平台的热修复技术,是通过下发补丁包,让已安装的客户端动态完成更新,让用户可以不用重新安装APP,就能够修复软件缺陷的一种技术,同时还可以发布一些轻量级的新功能。
常见的热修复技术框架如:Tinker、Robust、阿里百川等,也可自研。
附Tinker热修复原理探究(作者:本人):https://www.jianshu.com/p/fd9ed8b720ef
3.6 日志收集与统计
App发布之后,我们通常都会有需要知道C端的下载、安装、使用与错误情况,业务部门也会提出数据采集、业务检测、用户行为分析、稳定性监控等多样化的需求,因此App需要接入监控与统计工具,通常能解决的需求包括:
新增用户数、活跃用户数、启动次数与其趋势统计
版本分布与其趋势统计
活跃时段与渠道分析
用户使用时长、频率与页面访问路径
事件埋点与转化率统计
设备、网络、地域分布与统计
崩溃错误日志的收集与统计
常见的统计技术框架如:友盟、百度等,也可自研。
第四章 流程管理与质量体系
4.1 项目流程管理(交付型)
设定项目管理或PMO岗,制定并执行全生命周期项目管理流程,解决DoD(Definition OF Done)的问题,分清楚上下游流程的边界,定义清交付物清单及模板标准,减少多余的沟通与返工的可能,关键流程与文档需要正式的邮件留痕。
项目立项
项目可行性分析、立项评审。
交付物:可行性分析报告、立项申请书、项目预算等。
售前阶段
建立客户关系、分析挖掘客户需求、技术可行性分析、成本评估、基线版本需求。
交付物:需求跟踪表、合同、产品评估表等。
项目启动
刷新项目与客户需求 、资源调配、里程碑划分、项目启动会、关键角色任命。
交付物:关键角色任命书、整体交付计划(粗)、成本与预算、项目启动报告等。
项目规划
交付需求留痕、确定项目交付模型、制定并评审交付计划。
交付物:需求交付清单、整体交付计划(细)。
方案设计->需求评审->研发实现->发布上线
功能清单梳理,产品设计与评审,开发、测试、运维等各职能端口按计划执行开发和交付,并符合质量要求决策点。
交付物:PRD、版本功能清单、版本迭代开发计划、系统架构设计、接口设计、数据库设计、代码、项目周报、测试用例、测试报告等。
阶段验收
验收各要素完成情况,截止验收前遗留的问题情况,验收前要决策的问题,阶段性周期复盘,项目变更约束,阶段客户培训。
交付物:项目验收报告,需求变更管理,阶段交付物,阶段复盘纪要等。
项目结项
内部验收,提交初验申请,初验,试运行,终验。
交付物:结项申请,初验申请,试运行申请,试运行报告,终验申请,终验报告。
项目维护
缺陷维护,日常维护,需求变更。
项目关闭
经验总结,资源释放,客户满意度调研。
交付物:总结报告、客户满意度报告、技术白皮书、解决方案文档。
4.2 安全管理
安全技术体系主要包括物理安全、网络安全、应用安全、数据安全。
4.2.1 服务器物理安全
登录服务器操作系统和数据库系统的用户都通过用户名和口令进行身份标识和鉴别。服务器网络部署在一个VPC网络(Virtual Private Cloud),所有服务器无法直接SSH连接,需要通过跳板机跳转,所有跳板机服务器设置IP白名单限制,对出网和入网端口进行限制,并对主机做相应的安全策略:
- 设置SSH空闲退出时间600秒;
- 用户认证最大失败数为4;
- 密码最小长度设置为8位,至少包含小写字母、大写字母、数字、特殊字符等4类字符中等3类;
- 没有密码的用户禁止登陆服务器;
- 每个月对密码进行更新。
4.2.2 网络安全
多个服务器与客户端网络之间通信全程采用数据加密方式进行网络传输,包括服务器间约定对称加密密钥、非对称数据加密、双向SSL认证等,保证通信安全,防止中间人攻击,传输的敏感数据需要脱敏。
4.2.3 应用安全
1. 发布包安全
(1) 采用v1,v2打包签名机制,确保APK完整性,防止APK篡改,确保应用程序和开发者的信任关系。
(2) 采用加固方案,提升APK破解难度。混淆仅仅针对源码的阅读难度上做处理,无法从根源防止反编译,有暴露敏感代码信息的可能,而加固可防止应用被逆向分析、反编译、二次打包,防止嵌入各类病毒、木马等恶意代码及低俗广告,从源头保护数据安全防止逆向破解。
2. 程序安全
(1) 正式版关闭debug模式,防止系统崩溃,获取和篡改用户敏感信息,甚至分析并且修改代码实现的业务逻辑实现业务数据和App数据。
(2) WebView安全:WebView js代码执行安全、请求证书不校验安全、本地数据访问安全、WebView 密码明文不保存。
(3) 进程安全:默认关闭组件进程访问(android:exported="fasle"),广播经量使用本地广播LocalBroadcastManager,通过广播和接收器必须加权限。
3. 数据安全
(1) 关闭程序应用数据备份权限(android:allowBackup="fasle")。将该属性显式设置为false 时,防止攻击者通过adb backup和 adb restore 对App 的应用数据进行备份和恢复,从而获取明文存储的用户敏感信息。
(2) 正式版关闭log开关,防止敏感数据通过log打印泄露。
(3) 密钥文件信息通过so库保存。
4. 本地文件数据,缓存数据,数据库数据目录安全
(1) SharePreference保存敏感配置数据采用AES加密。
(2) 本地数据库敏感消息数据采用AES加密。
敏感文件数据,缓存数据存放在应用目录权限内,敏感对外文件统一通过Provider方式对外暴露。
4.2.4 数据安全
建立完整的备份策略,能够对数据库和文件系统进行备份及恢复。
1. APP本地数据库数据加密策略
对用户信息数据或者其他需要缓存到本地的敏感数据进行加密处理后再存储,主要通过AES对称加密,密钥应存储在动态链接库中。
2. 服务器备份策略
(1) 对系统每月进行一次快照,备份数据保存三个月;
(2) 系统升级、打补丁等操作,要在操作之前进行一次快照,操作完成后进行一次快照,备份数据保存三个月。
3. 数据库备份策略
(1) 数据库备份策略采用全量+增量的模式备份,保证能够快速的恢复数据。如:每周星期日进行一次全量备份,周一至周六依据周日的全量进行增量备份,备份数据保存三个月;
(2) 系统升级不允许修改字段名称,不允许删除字段,如果对数据库有修改操作,在修改前先对修改的表做一次全量备份。
4. 日常巡检策略
(1) 操作系统巡检。操作系统巡检内容:CPU监控,内存监控,I/O监控(硬盘使用率),系统SWAP监控等。
(2) 数据库本身巡检。包含重点参数的检查,数据库状态的检查,自增ID的使用情况,以及主从状态的巡检,检查数据库本地备份的完整性。
4.3 文档管理
项目中所有文档需要清晰有效的分类管理与控制,实现项目文档有序的保管与规范流动,文档管理在线化。
包含但不仅限:全生命周期项目管理流程中的交付物文档、规范、资料库、路由表、组件说明、技术调研、分享材料、工作记录等。
第五章 落实步骤
方案的落地需要根据重要程度与依赖关系逐步落实,参考以下优先级顺序:
1 统一的工具与环境
2 编码规范、Code Review规范、分支管理规范
3 系统架构搭建
4 组件化框架搭建
5 安全体系的搭建
6 监控体系搭建
7 业务开发
8 其他
9 贯穿全程:文档管理、项目管理流程的逐步落实、持续重构、技术演进、团队开发能力提升、团队测试能力提升