一、前言

从事 Android 研发的工作有五年多的时间了,最近两年多的时间一直参与开发和维护神策数据 Android SDK[1]。两年时间,从懵懵懂懂到略有心得,希望通过本文介绍下 SDK 开发过程中的一些经验。期待对大家有所帮助,更期待能够得到大家的指导。

正式介绍 SDK 开发经验之前,我们先来回答两个问题:

1. 什么是 SDK ?

相信做过 Android 研发的同学,对很多第三方的 SDK 应该不会陌生,例如:极光 SDK、支付宝 SDK、微博 SDK 等。SDK 的全称是 Software Development Kit,翻译过来是软件开发工具包,通常是为辅助开发某类软件而编写的特定软件包。

2. App 开发与 SDK 开发有什么区别呢?

App 开发偏向于用户层面,从 UI 展示到业务逻辑处理,全程处理用户的行为。而 SDK 开发偏向于功能方面,注重功能的开发实现,关于 UI 的设计与开发占比很少。

基于上述两个事实,我们来看下 SDK 开发中的一些开发原则。

二、开发原则

2.1 基本原则

开发 SDK 中,最重要的一条基本原则是要尽可能的稳定,不能影响集成方的功能(例如:不能出现 crash、不能出现性能问题等)

随着越来越多的客户使用 SDK,对于 SDK 的要求越来越高。一旦 SDK 引起了崩溃等问题,会对许多 App 造成灾难性的影响。因此,对于 Android SDK 的开发来说,要注意 try…catch 的使用、对象的检查等

2.2 设计原则

在保证基本原则的前提下,开发 SDK 还存在一些通用的设计原则,下面我们来详细介绍下。

首先,需要明确 SDK 的作用是为集成方提供一些功能。因此,要努力降低用户的上手难度,并且要易于理解。其次,要使 SDK 代码易于维护。

具体而言,主要概括为下面几点:

2.2.1. 接口易用性

对于接口主要注意两点:

1. 控制接口数量

相信大家在做 App 开发时,都曾经抱怨过某个 SDK 真难用。一个 SDK 好不好用,关键就看接口的设计是否简单易用。对于集成方来说,并不会关注 SDK 的实现细节,能用一个接口实现的业务,坚决不用两个。

2. 注意接口命名

一个好的接口命名能够让调用者见名知意。如果能够做到不需要借助帮助文档就能使用的程度,就说明这个接口命名是成功的。例如,对于 Android 中设置点击事件的接口 setOnClickListener。

2.2.2. 编码规范

对于 SDK 开发来说,统一编码规范很重要,最好的状态是集成方看到代码就能知道是哪家厂商的 SDK。换句话说就是 SDK 的编码规范统一,形成自己公司的品牌效应,同时也方便集成方的使用。

对于编码规范,网上有众多厂商的规范模板。可以选择其中一个或者自定义编码规范,尽早统一代码风格。

2.2.3. 跨端一致性

对于同一套 SDK,尽量保持各端接口命名、实现逻辑的一致。在我们的开发过程中,也出现过由于跨端之间的逻辑有差异,导致客户在 Android 和 iOS 上体验不一致的问题,这会带来额外的支持工作。因此,对于涉及到多个端的需求设计,一定要进行详细的沟通和确认,防止出现接口命名和实现不一致的情况。

2.2.4. 避免依赖三方库

随着开源的普及,GitHub 上有很多经典的三方库供开发者使用。对于开发者,会经常使用到三方库。例如:网络请求 OkHttp、图片加载 Glide 等。但是,在 SDK 的开发中,一般的原则是尽量避免使用三方库。主要有以下几点原因:

* 避免与集成方由于使用相同的三方库引起的冲突,增加集成方的集成难度;

* 三方库会不断更新。如果引入三方库,则 SDK 需要及时保持更新,会增加额外的维护工作量;

* 由于引入三方库,出现问题时导致排查困难。

2.2.5. “小” 而 “精”

SDK 尽量要做到 “小” 而 “精”:

* “小” 是指 SDK 的体积要尽可能的小。避免造成集成方的 App 体积增加较大,不然会引起集成方的不满,甚至下架 SDK;

* “精” 是指功能要专注。例如:我们的 SDK 是用于埋点,如果提供很多常见的工具类显然是不合适的。

2.2.6. 兼容性

兼容性是每个开发者都会遇到的问题。在 SDK 开发中更要保证新版本对于旧版本的兼容,常见的兼容性问题分为两类:

1. 新老接口兼容性

一般出现接口兼容性的问题主要是由于最初需求考虑不完善,导致后面进行方案优化时引起接口的变更,使之前的接口成为历史的难题,最终造成删除难度大。因此,功能接口设计要考虑扩展性。

2. 新功能兼容性

这里的兼容性分为两个方面:接入新功能的 App 和未接入新功能的 App。

例如,当初我们 SDK 适配 OAID 的方案时,由于需要使用 MSA 提供的集成包才能获取,但是在 SDK 中一般是不轻易集成一个三方库的。

因此,在设计这个方案时,就需要让集成方自己集成三方库,SDK 中提供获取的代码逻辑。最终在确定开发方案时,就需要考虑到一部分集成方使用了该功能,需要保证该功能正常读取。一部分集成方没有使用到该功能,要确保无异常出现。一般这种兼容性问题会决定开发方案的技术实现。

三、完善的文档说明

3.1 接入指南

对于 SDK 的集成和使用、版本更新和接口介绍,一定要准备比较完善的用户接入指南。例如,我们的 SDK 接入指南[2]分为:

* 基本使用 (Android)[3]

* 全埋点 (Android)[4]

* SDK API (Android)[5]

尽管根据经验来看,有些开发者没有看文档的习惯。但是一份完整的指导文档还是非常有必要,它可以节省很多集成的成本和时间。

同时,文档要注意合理的规划设计。避免一份文档内容太多,造成阅读困难。对于使用性的部分,最好有示例代码进行展示。

3.2 测试报告

在实际的接入过程中,有很多集成方需要提供相关的性能测试说明,这部分的内容需要及早准备。测试报告可以通过研发协助测试进行输出,方便后续的支持工作,降低维护成本。

四、踩过的坑

4.1 不做臆想需求

在最初开发 SDK 时,经常会由客户的一个简单需求扩展为很多需求,导致最终增加了多个接口。尽管看似 SDK 非常灵活,但是多出来的接口增加了很多维护成本。

例如,我们做过一个开启 Fragment 名称采集的需求。客户提出的需求是通过文件配置,然后 SDK 进行读取,在实施的过程中就出现很多臆想需求:

* 如果有别的客户不想通过配置文件,想使用接口怎么办;

* 如果用户想删除配置文件中已配置项怎么办;

* 如果客户想恢复忽略的配置怎么办。

这些臆想的需求,会增加很多额外的工作和交付成本,并且没有实际的意义。因此,在 SDK 开发中一定要避免臆想的需求。

4.2 过多的接口

在 SDK 中经常会有很多初始化开关配置接口,这类接口一般是暴露 set 方法让用户去设置。通常在初始化时一次性配置,因此这类配置项一般就不需要提供 get 方法,避免接口太多。过多的接口会造成代码的维护成本增加,包括后期需要兼容的成本都会增加。

4.3 跨端一致性

对于 SDK 研发来说,常会遇到同一个需求需要在 Android、iOS 和 Web 三端同步实现,这就需要三端的研发和测试同学能够相互沟通,确保三端的逻辑实现一致。在这个过程中,最难把控的就是细节点的一致性。出现细节不一致的问题,通常是由于测试 case 很难覆盖到,研发同学没有针对细节流程进行沟通交流而导致的。

因此,为了避免这类问题,对于细节点的方案实现可以让三端的研发同学相互进行沟通交流,争取在研发阶段把不一致的细节暴露出来,防止出现线上不一致的问题。

五、总结

本文是对 Android SDK 的设计原则和开发经验的一些总结,希望通过本文能够抛砖引玉,和大家一起交流相关的开发经验。

 

参考文献:

[1][github.com/sensorsdata…](sensorsdata/sa-sdk-android

[2][manual.sensorsdata.cn/sa/latest/t…](manual.sensorsdata.cn/s)

[3][manual.sensorsdata.cn/sa/latest/t…](manual.sensorsdata.cn/s)

[4][manual.sensorsdata.cn/sa/latest/t…](manual.sensorsdata.cn/s)

[5][manual.sensorsdata.cn/sa/latest/t…](manual.sensorsdata.cn/s)