什么是 SDK?
Software Development Kit,提供一定功能或者能力的软件开发工具包,通常是为了辅助开发应用而实现的特定软件包、框架集合。例如支付包 SDK,微博 SDK等,SDK一般包含相关的文档,范例和工具。
App 开发和 SDK 开发区别
App 开发偏向用户层面, 从UI到业务逻辑处理,全程处理用户行为。
SDK 开发偏重功能方面,注重功能的开发,UI和交互相关的较少。
SDK 开发原则
稳定性
毕竟,提供给App使用,不能动不动就把人家App搞 crash 了。
站在SDK使用者角度来看,我们期望第三方的SDK服务应该是稳定高效的,体现在提供稳定可靠的服务,在不影响宿主稳定性的前提下足够的高效,这就要求我们SDK设计者在设计并实现SDK时要尽可能的做到以下几点:
- 对外提供稳定的API.SDK的API一旦确定,如无非常严重情况不可更改.作为提供服务方,发生API变更所带来的变更成本非常大.
- 对外提供稳定的业务.在稳定的API后,必须要有稳定的业务来支撑.
SDK运行时的稳定,作为服务提供方,我们必须确保SDK自身运行的稳定,并且保证接入方不会因为我们的SDK产生不稳定的情况. - 版本稳定更新.和面向普通用户的应用相比,SDK版本的迭代是非常缓慢的.并且需要尽可能的对开发者屏蔽迭代过程,以免给开发者带来不必要的适配开销.
易用性
容易接入,容易维护,容易理解
- 控制接口数量
对于集成方来说,并不会关注SDK实现细节,能用一个接口实现的业务,坚决不用两个。 - 接口编码规范
尽量做到不需要借助文档就能使用,说明接口命名是成功的。
一致性
对于统一套SDK,尽量保持各端接口命名,实现逻辑的一致,减少跨端的实现和理解成本
单一性
- 小而精
SDK 尽量做到小而精
小是指SDK的体积尽可能小,避免造成集成方App体积变大
精是指功能要专注,例如,埋点的SDK专注于埋点,提供一大堆工具类显然是不合适的 - 尽量避免引入三方库
高效性
- 更少的内存占用.在不使用多进程的情况下,SDK服务和宿主程序运行在同一进程中,这种情况下必须要求限制SDK内存的占用,不能因为说因为我们SDK占用太多的内存资源,导致应用的存活时间变短.
- 更少的内存抖动.在占用更少内存的前提下,SDK设计者必须刻意的减少反复GC造成的内存抖动问题.
- 更少的电量消耗.尽管很多时候无法对电量消耗做一个很好的权衡,但是仍然有一些可以参考的做法,比如减少使用耗电模块的时间.比如在使用定位服务时,不要求非常高的精度下优先使用网络定位而不是GPS定位.
- 更少的流量消耗.
兼容性
- 新旧接口兼容
- 新旧功能兼容
安全性
扩展性
一个优良的API首先是简单可靠的.在正常使用的情况下体现为稳定可靠的执行,在异常情况下体现为及时的告知使用者使用错误.初次之外,遵循一致的明明规则,并是所有的API呈现出一致的风格对开发而言无疑是个好消息。
其实就是书上说的
设计原则
Android 应用程序的开发使用 Java 编写,在架构上使用 MVC,鼓励组件之间的弱耦合。开发出编写可重用、可扩展、可维护、灵活性高的代码需要遵循以下原则。
“开—闭”原则(OCP):
一个软件实体应当对扩展开放,对修改关闭。这个原则说的是,在设计一个模块时,应当使这个模块可以在不被修改的前提下被扩展。换言之,应当允许在不必修改源代码的情况下改变这个模块的行为。
里氏代换原则(LSP):
一个软件实体如果使用的是一个基类的话,那么一定使用于其子类,而且它根本不能察觉出基类对象和子类对象的区别。
依赖倒转原则(DIP):
要依赖于抽象,不要依赖于具体。
接口隔离原则(ISP):
使用多个专门的接口比使用单一的总接口要好。一个类对另外一个类的依赖性应当是建立在最小的接口上的。
合成/聚合复用原则(CARP):
又称合成复用原则(CRP),就是在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分;新的对象通过向这些对象的委派达到复用已有功能的目的。简而言之就是:要尽量使用合成/聚合,尽量不使用继承。
迪米特法则(LoD):
又称最少知识原则(LKP),是说一个对象应当对其他对象尽可能少的了解。狭义的迪米特法则是指如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类,可以通过第三者转发这个调用。广义的迪米特法则是指一个模块设计得好坏的一个重要的标志就是该模块在多大的程度上将自己的内部数据与实现有关的细节隐藏起来。信息的隐藏非常重要的原因在于,它可以使各个子系统之间脱耦,从而允许它们独立地被开发、优化、使用、阅读及修改。
Android SDK设计规范与心得
原文链接:
SDK 必备功能
云更新控制
日志服务
无论系统大小,日志服务是基本的服务.一个良好的日志服务能够帮助我们快速的发现问题,定位缺陷,从而获得问题的解决方案.
SDK的日志服务和其他常见的日志服务并无太大的不同,但是要保证以下几点:
- 日志服务能够记录有效的信息,在SDK要关键位置进行打点.
- 日志服务上传日志信息到服务器时,要保证最大的可靠性,不能发生上传失败后抛弃日志的情况.
- 日志服务不能影响对正常的操作流程有过多的性能影响.SDK产生的日志信息往往是非常多的,因此必须考虑日志IO操作所带来的开销.
权限管理
设计SDK 应该避免踩的坑
臆想的需求
过多的接口
过时的文档
API 设计技巧
方法名表明用途
参数合法性检验
方法异常处理
避免过长参数
a. 通过使用Builder模式来实现
b. 通过使用辅助类,通常采用静态内部类的方式,具体见静态内部类的使用
c. 通过将多个参数封装成类对象
d. 通过将参数拆解成多个方法的参数
谨慎使用方法重载
谨慎使用变长参数
避免方法返回null
资源统一加前缀
避免apk集成打包后资源覆盖
SDK 版本管理策略
SDK版本号命名通由4部分组成,格式为:
V主版本号子版本号阶段版本号_日期版本号加希腊字母版本号.比如V1_1_2_161209_beta.
希腊字母版本号说明
Alpha版:内部测试版,此版本表示该软件在该阶段主要是以实现功能为主,Bug相对较多,需要继续修改,通常只在内部流通流通而不对外开放.
Beta版:外部测试版,该版本相对Alpha已经有了很大的改进,不存在严重的Bug,但还是存在一些缺陷,需要进一步的测试以检查和消除Bug.
RC版:该版本已经相当成熟,不存在导致错误的Bug.与正式版相差无几.
Release版:该版本意味着”最终版本”,是最终交付用户或者公开发布的版本,也称为标准版.需要注意的是,该版本在发布的时候回以符合R来代替Release单词.
版本号修改规则
主版本号变化:当功能模块有较大的变化或者整体架构发生变化
子版本号变化:当功能有一定变化
阶段版本号变化:一般是Bug修复或者较小的变动,根据反馈,需要经常发布修订版本.
日期版本号(161209):用于记录修改项目的当前日期,每天对项目的修改都要更改日期版本号.
希腊字母版本号:此版本号用于标注当前软件处于那个开发阶段,当软件进入到另一个阶段是需要修改.
API版本管理
和普通应用API版本管理不同,SDK设计者需要着重关注SDK API的管理.原则上SDK API一旦公开发布后其状态(签名和具体实现)应为不可变.
对于特殊情况下API的变更,需要遵守”开闭原则”,即一个类,模块,方法应该对扩展开发,对修改关闭.这就要求我们做到以下几点:
- 在需要调整SDK API时,优先选择添加新方法,而不是在原方法上修改.对于实现相同功能的新方法,尽可能的要兼容原始方法.
- 在需要废除某些方法时,需要在正式版发版前使用@deprecated标识,并给出替代方案和废弃的时间(通常是SDK版本号)
接入文档和API文档版本管理
接入文档是用来告诉SDK使用者,如何使用SDK,使用的详细步骤和可能发生的问题
接入文档通常分为两份:内部版和公开版.
- 内部版通常用于内部开发人员和测试人员,信息较为详细
- 公开版则是面向开发者,相比内部版会省略的一些信息.
API文档其实就是对SDK API的更详细说明,类似java中的api doc,可以借助jdk的自带javadoc直接生成,当然在android studio也提供了便捷的生成方式.
无论是接入文档还是api说明文档,其变更一般发生在SDK版本发生变化时.当SDK发生变更时,文档必须随之更新,不能出现SDK更新后说明文档不与之匹配的情况.
集成Demo版本管理
集成Demo通常是一个简单的app,用来展示如何快速的接入SDK.其版本变