温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何开发Android SDK

发布时间:2021-10-21 09:20:05 来源:亿速云 阅读:209 作者:iii 栏目:移动开发

本篇内容介绍了“如何开发Android SDK”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

1. SDK 是什么

相信做 Android 开发的朋友,一定使用过第三方的 SDK,比如推送 SDK、分享 SDK 等。SDK 的全称是 Software  Development Kit,翻译为“软件开发工具包”。SDK 通常是为辅助开发某类软件而编写的特定软件包、框架集合等。

SDK 可以分为系统 SDK 和应用 SDK。所谓系统 SDK 是为使用特定的软件框架、硬件平台等所开发的工具集合。而应用 SDK 则是基于系统 SDK  开发的独立于具体业务、拥有特定功能的工具集合。

SDK 的使用者主要是 B 端客户,最终交付产品是代码、示例和文档,客户接入 SDK 也是和 SDK  提供方交流的过程,对外沟通的成本比对内更高,遇到的问题也会更多。所以 SDK 开发对开发者的要求比对应用开发更高。能开发好 SDK  一定能开发好应用,但能开发好应用,未必能开发好 SDK。

2. SDK 实现目标

SDK 的实现目标,概括来说:简洁、稳定、高效。

简洁

对于用户而言,一款好的产品应该是简洁易用的,不该让他们花费太长的时间学习。SDK  也当如此,它不该出现复杂繁琐的对接工作,使用者通过阅读代码和文档,花费很少的时间就能做好 SDK 的对接。

比如当开发者需要使用 SDK 的服务时,只需要在代码中新增一行即可。在项目中初始化 SDK 只要一行代码,开发者不用关心  GLContext,内部已做好处理,也不用关心同步或异步问题。

public class FURenderer {     // 定义         public static void setup(Context context) {         //...     } } // 一行代码调用 FURenderer.setup(context);

稳定

站在 SDK 使用者角度来看,我们期望第三方 SDK 的服务是稳定高效的,体现在提供稳定可靠的服务,同时运行时性能要高效。这就要求我们在设计实现 SDK  时要尽可能做到以下几点:

  • 对外提供稳定的 API。SDK 的 API 一旦确定,除非特殊情况不可更改,提供方变更 API 的成本非常大。

  • 对外提供稳定的业务。在提供了稳定的 API 后,必须要有稳定的业务作为支撑。

  • 运行时的稳定。确保 SDK 自身稳定运行,不能出现因为接入了 SDK 而导致宿主应用不稳定的情况。

  • 版本稳定更新。SDK 版本迭代非常缓慢,要尽可能对使用者屏蔽迭代过程,避免带来不必要的适配成本。

高效

无论是普通的应用开发还是 SDK 开发,都应该考虑到性能问题,SDK 设计者要着重考虑以下问题:

  • 更少的内存占用。一般 SDK 和 App 运行在同一进程,此时 SDK 要管理好自己占用的内存,合理分配,注意释放。

  • 更少的内存抖动。在占用更少内存的前提下,SDK 设计者必须减少频繁 GC 造成的内存抖动问题。

  • 更少的电量消耗。低电量消耗和高性能表现之间很难做到权衡,可以从 CPU 计算量、屏幕刷新帧率等角度考量。

3. SDK 架构设计

SDK 的架构实现决定了后续的维护难度,所以最好能够结合实际业务确定合适的方案。以项目中的模块化开发为例,讲讲架构设计的原则。

遵循面向对象开发的几大原则,目的是达到三个目标:可维护性、可重用性和可扩展性。具体来讲:

  • 根据单一职责原则,将系统拆分为多个小模块,每个模块保持相对独立,降低实现类的复杂度。

  • 根据接口隔离原则,为每个模块定义契约接口,接口的粒度要小,功能要细,越细小越易维护。

  • 模块之间通过协议或接口通信,避免直接相互依赖,以降低耦合,互相了解最少,体现了迪米特法则。

  • 根据开闭原则,定义各个模块的公共行为,通过模版方法设计模式提供骨架实现,易于功能扩展。

  • 根据组合优于继承的原则,当多个模块功能叠加时,使用类的组合保证设计的灵活性。

比如项目第三方 demo 的功能模块借鉴了 Java 集合框架的架构,分为契约接口、抽象类和具体实现三部分。

  • 首先定义 IEffectModule 作为特效的契约接口,包括创建、设置参数、销毁等各个功能模块的公共操作。

  • AbstractEffectModule 作为 IEffectModule 的骨架实现,实现了共同使用的方法,定义了公共的成员变量。

  • 定义美颜 IFaceBeautyModule 接口,其继承 IEffectModule 接口,包括额外的设置参数操作,FaceBeautyModule  作为其实现类,同时继承 AbstractEffectModule,复用基类的代码。

  • 美妆美体模块类似,先定义契约接口,然后定义具体实现,接口间相互隔离,接口内高度内聚。

  • FURenderer 实现 IFURenderer 渲染接口和 IModuleManager 模块管理接口,组合各个功能模块。

如何开发Android SDK

4. SDK 设计规范

API 设计在任何开发中都非常重要,许多时候软件的质量好坏体现在 API 的设计上。在普通的应用开发中,API  只会在开发人员间流通,不会暴露给非本应用开发的其他人员。但是 SDK 作为一种服务,需要向开发者暴露一部分 API,这样才能使用 SDK 的服务。

下面列出一些应该重点关注的原则。

方法名表明其用途

好的方法名最直观表明它的功能,名字是自解释的,不需要额外的文档,这样做会减少不必要的沟通成本。对于开发者而言,还有什么比直接读代码更直观呢?《重构》一书中讲到,要像给自己孩子起名一样给每个变量命名,这个要求不算过分吧。

参数的合法性检验

如果程序运行时出现异常,会破坏使用者的体验,影响非常不好。我们采用“防御式编程”的思想,能够避免非法输入对系统的破坏性。

当合法性校验不通过时,针对方法权限不同分别对应不同不同的处理策略:

  • 对于公开方法显式检查抛出异常,并使用 @throw 来说明抛出异常的原因

  • 对于私有方法通过断言的方式来检查参数的合法。

  • 检查构造方法的参数的合法性,以使对象处在统一状态。

需要注意的是,如果检查的代价太大,那就需要综合考量。

方法只实现单一功能

一个方法应该具有单一的功能,尽可能做更少、更专的事情,这也是单一职责原则的体现。“阿里巴巴代码规约”规定一个方法最好不要超过 80  行,对庞大的方法要拆分成更小的。

另外注意,宁可提供小而美的方法也不要提供大而全的方法,大而全的方法往往经常发生变动,产生风险的可能性更高。因此不如提供更小的方法以便组合使用,小而美的方法更易做到代码复用。

访问权限控制

包括类方法的权限和变量的权限,能声明私有的不要公开,外部知道得越少越好。能声明静态的方法就用静态,静态方法天然线程安全,体现继承关系的用  protected 修饰,确保公开的方法和变量是安全可靠的。

避免过长参数

过长的参数会造成记忆上困难,还有调用传参容易出错,应当尽力避免。在无法避免过长参数的情况下,考虑其他的方法进行解决:

  • 通过使用 Builder 模式来实现

  • 通过将多个参数封装成类对象

例如,项目里有个方法,参数非常多。

int onDrawFrameSingleInput(byte[] img, int w, int h, int format, byte[] readBackImg, int readBackW, int readBackH);

重构后,把参数封装成对象,调用方法只用构造一个对象传入,避免大量参数带来不好的体验感。

public class VideoFrame {     private int width;     private int height;     private byte[] data;     private byte[] readback;     private int readbackWidth;     private int readbackHeight;     private int pixelFormat;     // ... }  int onDrawFrameSingleInput(VideoFrame videoFrame);

慎用方法重载

滥用重载容易让开发者感到疑惑,在需要重载方法的时候,可以使用不同方法名来代替。对于构造函数,可以通过静态工厂来代替重载。

Java 中提供的 ObjectOutputStream 类就是个很好的示范:它的 write 对于每个基本类型都有一个变形,比如写出字符、写出  boolean 等操作。设计者并没有使用重载将其设计成 write(Long l)、write(Boolean b),而是将其设计为  writeLong(l)、writeBoolean(b)。

例如,项目对外的处理方法全部是重载,只能根据参数区分,迷惑性非常大。修改为不同的方法名后,看到名字就知道要调用的方法,清楚了不少。

// 重构前 int onDrawFrame(byte[] img, int tex, int w, int h); int onDrawFrame(byte[] img, int w, int h); // 重构后 int onDrawFrameDualInput(byte[] img, int tex, int w, int h); int onDrawFrameSingleInput(byte[] img, int w, int h, int format);

避免方法直接返回 null

对于需要返回数组或集合的方法,不要返回null。比如我们去买糕点店买面包,面包没了是一种正常状态,就不应该返回 null,而是返回长度为 0  的数组或集合。Java 提供了 Collections.emptyXXX() 表示空集合。

避免引入第三方库

GitHub有许多开源的第三方库,比如网络请求 OkHttp、图片加载 Glide 等,但在 SDK 开发中,遵循的基本的原则是:

  • 最小可用性原则,即用最少的代码,如无必要勿增实体。

  • 最少依赖性原则,即用最低限度的外部依赖,如无必要勿增依赖。

引入第三方库可能带来下面几个问题:

  • 宿主应用的第三方库和 SDK 依赖的版本不一致,容易引起冲突,增加对接的成本。

  • 开源库不断更新,SDK 也要及时更新,增加额外的维护工作量。

  • 由于引入开源库,出现问题难以排查。

保证兼容性

SDK 是不断迭代的,每次发布都会有新功能和 bug  修复。对于使用者来说,升级版本不该有太大的改动,一般直接替换库文件或者修改远程依赖库的版本号就够了。避免直接对公开接口的重命名,如果旧接口废弃,要通过  @Deprecated 关键字标明,并给出替代方案和废弃的时间。

减少入侵性

要保证较少的代码侵入主要在对外提供服务时,充分考虑开发者的使用场景来设计优良的 API。一套优良的 API  在定义时要满足绝大数开发者预期的方式——语义上要求通俗易懂,使用上要求简单可靠。具体的表现是,在正常情况下能够稳定可靠地运行,在异常情况下及时地反馈错误信息。

比如使用 Gradle 下载依赖库,AAR 包中有不必要的 bundle 资源,我们提供了打包 apk 时的构建配置,自由选择要打包的  bundle,减少了对宿主应用的侵入性。

applicationVariants.all { variant ->       variant.mergeAssetsProvider.configure {           doLast {               delete(fileTree(dir: outputDir,                       // 删除不必要的 bundle 文件                       includes: ['model/ai_face_processor_lite.bundle',                                  'model/ai_gesture.bundle',                                  'graphics/controller.bundle',                                  'graphics/tongue.bundle']))           }       }   }

5. SDK 交付

封装包

Android 平台通常使用 jar 和 aar 发布 SDK,区别是 jar 只包含代码,aar 可以包含代码、资源和动态库。一般而言 aar  是最合适的交付方式,把它上传到 maven 服务器,使用者就可以一行代码集成。对于需要灵活定制的客户,我们也会提供 SDK  的源码,弊端就是升级困难,要改动很多的代码。

对于代码混淆,公开接口和 native 使用的接口不要混,内部的实现细节可以混淆,以减少 SDK 包的大小。

接入文档

接入文档用来告诉 SDK 使用者,如何使用 SDK、详细步使用骤和可能发生的问题。文档内容包括:更新记录、基本信息、API  说明、集成步骤、FAQ等。好文档的标准就是清晰明了,通俗易懂。一个完全不懂 SDK  的开发者看着文档就能对接,对于经常遇到的问题要逐条列出,专业名词要有对应的解释。

Demo 示例

集成 Demo 通常是一个简单的 App,用来展示如何快速地接入 SDK。Demo 的源码托管到 GitHub,方便使用者参考,其版本变更策略和 SDK  版本的变化保持一致。尽管是个 Demo,它的开发原则也要与 SDK 一致,确保高质量的交付。

“如何开发Android SDK”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI