编程进阶网编程进阶网
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 01.设计高效日志框架库
  • 02.国际化项目方案实践
  • 03.设计通用缓存框架
  • 04.设计轻量级线程池库
  • 05.设计通用轮训方案
  • 06.设计异步线程框架
  • 07.设计隐私合规检测库
  • /zh/android/plan/08.设备串口通信实践.html
  • 09.设计TTS语音实践
  • 10.设计悬浮窗开发实践
  • 13.SDK基础架构实践

13.SDK基础架构实践

目录介绍

  • 01.SDK设计原则
  • 02.SDK设计注意点
    • 2.1 减少三方依赖
    • 2.2 体积和功能
  • 03.SDK基础设计
    • 3.1 整体架构图
    • 3.2 UML设计图
    • 3.3 关键流程图
    • 3.4 接口设计图
    • 3.5 模块间依赖关系
  • 04.SDK设计思维点
    • 4.1 基于接口开发
    • 4.2 访问权限控制
    • 4.3
  • 05.SDK设计技术点
    • 5.3 Provider初始化
  • 06.SDK其他设计点
    • 6.1 兼容性设计
    • 6.2 稳定性设计
    • 6.3 灰度设计
    • 6.4 降级设计
    • 6.5 异常设计
    • 6.6 埋点设计
    • 6.7 安全性设计
    • 6.8 文档规范设计

02.SDK设计注意点

2.1 减少三方依赖

  • 经常碰到的一个问题
    • 使用方会说你们的sdk是一个大礼包啊,为啥会有这么多的仓库依赖啊。明明只用了你们一小部分功能,但是因为用了SDK,所以被引入了一大推的依赖。
    • 举个例子网络库,数据埋点,图片库等等一大堆东西都会被依赖进来。所以在没有使用的情况下,sdk所需要的就是用最小的依赖关系,来完成你所需要的功能。

2.2 体积和功能

  • 三个字形容:小而精。小是指包的体积要尽可能的小。精针对的就是 SDK 的功能了,一定要专注于特定功能。
  • 体积上:
    • 去除无用资源(主要是图片和so库)和代码;不要依赖第三方库,至少大体积的库是不可以的;优化代码结构,去除冗余的代码逻辑;
  • 功能上:
    • SDK 讲究功能专一,去除那些花里胡哨的东西;基本功能完善,适用于所有的业务线;根据业务方的需求反馈,考虑优化或者丰富 SDK 功能;

05.SDK设计技术点

5.3 Provider初始化

5.3.1 Provider为何可以初始化
  • sdk初始化方式:
    • 一般通常是在Application的attachBaseContext或onCreate执行初始化操作;也有一部分是使用ContentProvider初始化sdk。
  • ContentProvider初始化sdk
    • 低侵入的方式集成,解耦等特点。在AndroidManifest文件中声明ContentProvider,代替Application的onCreate()中添加init()方法。
  • ContentProvider和Application初始化次序
    • Application#attachBaseContext() → ContentProvider#attachInfo() → ContentProvider#onCreate() → Application#onCreate()
    • ContentProvider的onCreate刚好处于Application#attachBaseContext()和Application#onCreate()中间,并且也能获取Context,也具备了初始化SDK的能力。
5.3.2 Provider初始化优缺点
  • 优点:低侵入接入,不需要手动添加初始化代码,降低接入成本;降低耦合度,抽离代码方便。
  • 缺点:多个SDK使用ContentProvider初始化,无法保证不同SDK初始化循序;最好注意多个ContentProvider初始化的时长,加载完毕才会执行Application#onCreate的调用;注意暴露风险,声明provider的时候,配置exported为false。

06.SDK其他设计点

6.1 兼容性设计

  • 对外接口( API )的兼容性
    • 每次版本更新后,对外接口要尽可能保持不变。对于更改较大的接口,可以使用 @Deprecated 注解对老接口进行标记,并且做新接口调用的兼容,而不是直接删除老接口。
  • 功能的兼容性
    • 在不影响整体功能和项目结构的基础上提供部分业务的需求定制化,可以形成配置项
  • 支持版本兼容性
    • minSdkVersion 的值应该尽可能的小,当然现在市场上基本都是 4.4 以上的手机了。这也从侧面要求不要随便依赖第三方库。

6.2 稳定性设计

  • SDK 极其注重稳定性,要保证在不同 APP 环境下都能正常工作。如果出现问题就会导致发新版本,一方面要通知所有业务方做版本更新(这是一件很麻烦的事),另一方面会打乱业务方 APP 的版本更新安排(这个锅背定了...)。
  • 版本迭代要稳定:一般版本号都采用 x.y.z 模式,对于小功能或者是小的修复,增加 z 值即可,不能影响已经上线的服务。
  • 对于大版本的改动,增加 y 值甚至 x 值后,需要让 PM 告知业务方下次发版时使用最新版本的 SDK (如果是大 BUG 的修复,那就必须强制要求业务方更新了)。 SDK 上线前必须经过完整的测试流程,保证功能正确、性能达到要求、对不同机型进行适配、对不同 Android 版本进行适配。业务方接入后,可以让业务方也走一遍测试,提供反馈报告。 SDK 的结构设计应该要有好的扩展性,比如接入一个新功能,就不能影响整体的代码框架,否则可能造成一些潜在的威胁,也会增加测试的工作量。

6.3 灰度设计

6.4 降级设计

6.5 异常设计

  • 数据上报数据分析很重要
    • 另外还需要有线上的异常用户数据回捞系统,方便开发同学主动去把线上有异常的用户的日志给收集回来。

6.6 埋点设计

  • 这一块可以通过接口回调处理

6.7 安全性设计

SDK 也是有必要保证安全性的。

SDK 混淆、加固、安全审核,这个一般是公司级别的安全管控。针对安全报告做对应修复即可。 隐私数据的保护,必须进行加密或者掩码处理。比如:本地保存用户的登录态,手机号的掩码显示等。 网络请求时的数据加密保护,部门一般都有自己的加密机制,大部分都是模仿 ssl 握手协议,采用非对称加密和对称加密结合的方式。更严格的话,可以增加自定义证书校验,不过这个成本较高。 对于 SDK 中接入的部分第三方功能或者服务需要提供云控机制。因为第三方服务存在不稳定性和弱安全性。

6.8 文档规范设计

  • 这个是被广泛忽视的一点,文档真的很重要!文档真的很重要!文档真的很重要!
  • lib库的最终形态中一定要包含接入文档和演示 Demo 。虽然大部分业务方都不看文档,但你一定要写(至少甩锅的时候好甩...)。至于演示 Demo ,一定要考虑尽可能多的场景,把 Lib 的功能都展示出来。
  • 文档要尽可能详细,但最好不要把所有内容都集中在一个文档里面,这样导致文档过长,业务方更加反感阅读。可以对文档做细划,比如:如何接入(jar、aar?或者是离线包还是 maven 库?)、基本功能如何使用(大部分业务只需要基本功能)、定制化功能如何使用、接入中可能遇到什么问题、怎么解决这些问题等等。
贡献者: yangchong211
上一篇
10.设计悬浮窗开发实践