ygunoil

SDK全称 Software Development Kit,广义上的 SDK 是为特定的软件包、软件框架、硬件平台、操作系统等建立应用程序时所使用的开发工具的集合,狭义上的 SDK 则是基于系统 SDK 进行开发包装的、新的、独立的、能够完成特定功能并返回相关数据的一组工具的集合。

插件(Plug-in,又称addin、add-in、addon或add-on,又译外挂)是一种遵循一定规范的应用程序接口编写出来的程序。其只能运行在程序规定的系统平台下(可能同时支持多个平台),而不能脱离指定的平台单独运行。因为插件需要调用原纯净系统提供的函数库或者数据。很多软件都有插件,插件有无数种。

sdk可以看做插件的集合;

推荐一个BLE蓝牙研究的库,正在做该方面的或者有兴趣的可以看下。

Android BLE蓝牙框架,包括扫描、连接、设置通知、发送数据、读取和接收数据以及各种直观的回调,近乎一行代码植入项目,可扩展配置蓝牙相关操作。

https://github.com/Alex-Jerry/BleDemo

http://www.jianshu.com/p/d70e22ce61bc

本文作者

作者:brucevanfdm

链接:

http://www.jianshu.com/p/8f39919cd4e5

本文由作者授权发布。

1

前言

最近由于工作需要,将应用里的部分功能独立了出来,封装成 SDK 提供给合作伙伴使用。由于经验不足,网上也没多少写这方面内容的文章,遇到了不少的坑,决定记录下来。

其实,刚说到要写SDK也有点慌,印象中SDK一直是个复杂的东西,脑海中浮现的是Java SDK ,Android SDK这类庞然大物。

SDK全称 Software Development Kit,广义上的 SDK 是为特定的软件包、软件框架、硬件平台、操作系统等建立应用程序时所使用的开发工具的集合,狭义上的 SDK 则是基于系统 SDK 进行开发包装的、新的、独立的、能够完成特定功能并返回相关数据的一组工具的集合。

听起来一愣一愣的,其实,将一些业务逻辑独立出来,打包成jar、so、aar,暴露一些APIs给外部调用,也可以称为SDK。如推送SDK,支付SDK,地图SDK...既然是所谓的集合,那么自然有大有小。

下面说说我在封装SDK与使用的时候遇到的那些事,希望对大家有些帮助吧!

2

二次打包aar

大多时候,我们的业务依赖于第三方库,载体可能为jar、so、aar,如果是jar包那好办,直接丢进libs目录下就可以了;so库就不简单了,不少开发商只提供少数abi的so库,这时就需要根据需求选择了,要么全部一份,要么只保留一个目录,否则就会报错;aar则是包含了代码、资源(图片、布局等)、so库等的集合。

那么需求来了,如何将第三方aar包二次封装,加入自己的业务逻辑再打包成一个aar呢?其实这个问题我也没有找到直接的解决方案,如果你有,请联系我,感激不尽!但是这个问题又是可以曲线解决的,aar其实就是个压缩包而已,如下图所示:

Android Studio导入aar时也是将其视为一个module(library),使用其中的classes以及其他资源文件,那我们可不可以直接将其解压,直接导入?

这样就避免了在aar的基础上封装成aar!跳过这个坑?实践证明确实是可以的。如果你要封装的aar只包含了jar包和so库,那就简单了,解压出来分别导入项目相关目录即可!不然可能就要手动合并某些资源了...更新:详情请看 二次打包(封装)AAR实用指南

http://www.jianshu.com/p/3bad128bd106

还是期待谷歌能给出一个傻瓜式的一键合并方案吧!

3

SDK中Application对象的初始化

有次SDK接入方反馈说某个地方崩溃了,一看Log,是调用Application对象中的方法空指针了。我一想,混淆?不是。导入姿势不对?不是。文档没认真看?也不是?Demo可以正常运行啊......随即想到是接入方自定义Application对象的问题。

如果aar中定义了Application,theme,icon,那么编译时就要抛出如下异常:

-编译错误AndroidManifest合并异常-

由于项目与aar都定义了自己的Application,编译器不知道用谁的,这就产生了上图的异常,按照提示,在Application标签下添加如下代码:

tools:replace="android:name"

合并方案可以参考官方文档:合并多个清单文件| Android Studio - Android Developers

https://developer.android.com/studio/build/manifest-merge.html?hl=zh-cn

理虽如此,但是你很大概率就掉坑了,这个方案直接将SDK中的Application对象替换为你的,换句话说就是SDK中的Application对象根本没有初始化,这就是上文说的空指针的罪魁祸首了!

确实之前在写文档的时候没有考虑到自定义Application的情况,还是经验不足啊!甚至一度将Application里初始化的方法全部移出来,后来转念一想,让接入方继承我的Application不就OK了吗!!测试一波,赶紧更新下文档,不然又被吐槽了...这下理解为什么接入某些第三方SDK时,有的会要求继承SDK里定义的Application对象。

4

Application多继承

作为一个SDK提供方,假如你的SDK需要用户继承你的Application,我觉得应当提供一个Application多继承的解决方案,毕竟用户可能不仅仅只用你一个SDK,当有多个SDK有这个需求时就尴尬了。

java 多继承,这里的需求是继承两个类,并不是通过实现接口的方式“继承”多个接口上的方法声明。语言原生不支持,这样就比较麻烦了。

解决办法如下:

通过接口实现 + 反射 的方式来创建代理Application对象,曲线实现Application的多继承,由于代码较多,这里就不贴源码了,解决方案:ApplicationProxyDemo 源码配合注释食用,风味更佳!

https://github.com/brucevanfdm/ApplicationProxyDemo

5

导入aar的两种方法

解决一:采用Android Studio新建module的方法,选择jar/aar即可。

导入.AAR

解决二:使用gradle脚本直接导入:

1. 在项目build.gradle文件内android{}标签中加入如下代码申明本地仓库:

repositories{

flatDir{

dirs\'libs\'

}

}

}

2. 然后将aar包放入libs目录(没有就在app目录下创建一个),随后加入dependencies :

dependencies{

compilefileTree(dir: \'libs\', include: [ \'*.jar\'])

...

compile(name: \'xxxxxx-xxxx\', ext: \'aar\') //name为aar文件全名

}

6

SDK中不可忽视的混淆问题

1. 常规的避免混淆,比如一些第三方类库中的要求

2. 避免混淆对外提供方法与数据实体的类,并且添加到接入方的proguard-rules.pro中。

最后

其实在最近的SDK开发与对接中遇到了不少问题,但是也学到了不少东西,由于缺少相关经验,也在不断的摸索之中。正所谓实战出真知,纸上谈兵容易,真刀真枪时就会暴露出一些问题,还是要多动手。当然了,技术都是业务驱动的。

1. 修改类别文件名及类别方法。

开发SDK时通常会用到比较多的第三方的类别方法, 这样的话, 开发者在使用你的SDK时, 因为他可能也会加一些第三方的开源库, 比如都使用了NSString的md5类别文件。 由于这两个文件都是从网上下载来下的, 所以文件名是一样的。 这样在编译时就会报错。 然后就想到要去修改这个类别文件名, 等修改类别文件名后。 发现类别中的方法名是一样的, 而ios在调用两个相同方法的类别方法时, 不能确定其调用的哪个方法, 但可以肯定地是只会调用一个类别方法, 如果恰好开发者自己又修改了这个类别方法, 那就有问题了。 

所以在SDK开发过程中, 需要修改引入进来的类名, 及方法名, 建议添加项目前缀, 最好是三个字母的, 如NAB, (两个字母为苹果自己保留使用)

 

2. 在开发SDK时, 如果发现某个方法命名时比较困难, 那么几乎可以肯定的是, 这个方法藕合度太高,需要再次进行分解。

 

3. 开发SDK时, 需要考虑到升级的问题, 并且可以指定某些版本必须强制升级。 (以防某些版本到后期发现有明显问题, 需要及时替换)

 

4. 开发SDK时, 需要留出一个接口, 能通过后台服务器强制关闭掉某个接入应用的调用。 (这可能会发生在恶意地攻击行为, 以及非恶意地使用行为,如某应用频繁自动重启事故,每次重启都会调用咱们的SDK,然后就会使得咱们的SDK服务器压力陡增), 这个时候, 如果后台能根据这个应用的APP ID啥的, 强制关闭它发的请求,或者屏掉他的请求, 你会发现世界如此美好。

 

5. 统计方面, SDK存储每个接口调用的次数,以在一定的情况下发送给服务器, 便于后期分析某些接口是否有问题,或者是根本就没有用户使用的情况。

 

6. 有些SDK使用的前提条件,最好是在编译期就提示给用户,而不是在运行期, 可以使用类似下面代码来进行提示

#warning - Release scheme, this is not work.

 

 

#if !__has_feature(objc_arc)

#error iBeaconSDK requires automatic reference counting

#endif

分类:

技术点:

相关文章: