目前,公司需要开发一套iOS和安卓的sdk,主要包含蓝牙管理、网络请求、倒计时等方案执行、蓝牙数据交互等功能。之前没有过开发安卓sdk的经历,写个笔记用以记录。
现在iOS sdk已经写了一部分,安卓开发我也习惯从iOS的角度类比来开发,节省时间。在开始具体开发之前,先将几个问题具体弄清楚,然后再一步步具体进行。
问题1: 与iOS的类比,是否可以生成类似iOS的静态库.a
或者动态库.dylib
来给第三方使用?
在安卓开发中,并没有.a
静态库和.dylib
这种动态库,但是有另外类似的两种形式:JAR
和AAR
。
.a
静态库,但是只能包含java代码,不能包含资源文件(例如XML布局,Android的Manifest.xml,本地库(.so文件等))。一般情况下,我们会将Android库打包成AAR文件,然后在需要的项目中添加对应的依赖。在Android Studio中,可以使用Gradle
构建工具来生成AAR
文件,然后在需要使用SDK的项目中,在build.gradle
文件中添加对应的依赖。
例如:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.example:my-sdk:1.0.0'
}
需要注意的是,使用AAR
文件并不能完全隐藏SDK的实现细节。在Android中,所有的Java代码都可以被反编译。如果想保护代码,需要使用混淆工具
(例如ProGuard
)对代码进行混淆,使得反编译后的代码难以阅读和理解。
问题2: 使用gradle安装的sdk,这个aar也像iOS一样有类似cocoapods的仓库吗?
是的,像iOS常用的cocoapods库一样,在安卓中可以将sdk发布到Maven
仓库,如JCenter
、Maven Central
或JitPack
,然后在build.gradle
文件中添加远程库依赖。这种方式最为常见,它也允许其他开发者很容易地使用和更新你的sdk
。
当然,也可以不发布到这些仓库。让开发者直接下载aar,然后放在libs
目录下,然后在项目的build.gradle
文件中添加本地库依赖。这种方式适用于SDK
尚未发布,或只在少数项目中使用的情况。
第3中方式,也可以通过自己服务器分发或者私有Maven仓库
来分发。
问题3:安卓封装成AAR的sdk,是否像sdk的动态库或者静态库那样,能看到对应的头文件及具体可以调用的方法?
两个平台还是有蛮大的差异。在iOS使用的.a
静态库时,一般会将header
头文件暴露给三方使用者,而具体实现则在.a
里面变为二进制文件无法查看。但在安卓中,AAR
中包含的实际上是Java的.class
和kotlin
编译后的字节码。不考虑通过工具反编译等因素的话,直接是不能查看其源代码的。给第三方使用时,更加依赖于文档说明、示例代码等。
问题4:sdk如何设置具体开发?是否像iOS按照cocoapods库开发一样麻烦呢?
安卓开发在这种场景下反而比iOS要简单不少。在Android Studio
中,直接创建一个Library
模块,然后按照自己规模的模式进行封装和开发即可。本身这个模块也可以很方便地配置自己所依赖的三方库等。而在iOS的SDK开发中,需要依赖CocoaPods
或者Carthage
等工具。
在整个SDK开发完成后,也可以用如下简单的命令来生成AAR
文件。
./gradlew :my-sdk:assembleRelease
这个命令则会在my-sdk/build/outputs/aar/
目录下生成一个名为my-sdk-release.aar
的文件(假设模块的名字是my-sdk
)。然后,便可以将这个AAR
文件分发给其他的开发者,或者上传到Maven仓库中供其他人使用。
也可以通过Android Studio
的界面来执行这个构建任务。具体在Gradle
窗口中找到你的模块,展开Tasks
->build
,然后双击assembleRelease
任务。
问题5:Android sdk开发,语言如何选择?java还是kotlin?
在iOS的sdk开发上,我选择了Objective-C
。主要出于两个原因:
Objective-C
这种将声明和实现分分别在两个文件中来写的语言,天然地更加适合sdk开发。私有的属性和方法,可以直接写在.m
文件中,给三方调用的,直接写在.h
中,更加清晰。虽然调试过程中,私有的属性和方法等,不可避免地也会暴露,但是在正常情况下,它更加简单和容易。Swift
苹果也推了好多年了,但是,在互操作性方面,在Swift
里面调用oc
代码,基本上没有什么问题。但是反过来可能就有些问题。毕竟Swift与OC相差年代太多了,两者不是一个代际的语言,Swift上面有许多特性,OC并不支持。比如泛型
、枚举的关联值
、结构体
、协议扩展
和某些类型的方法重载
,这些在OC中都无法使用。在设计SDK时,需要注意公开API要遵循Objective-C的特性和约束。与其各种注意,不如直接用OC来开发。在兼容和稳定性方面应该问题更小。而在Android SDK的开发上,同样是Google推出的新语言kotlin,它与Java之间的互相调用却更加无缝,虽然它们之间也有着一些细微的差异和限制。并且,kotlin和java都是一个类为一个单文件的代码,并没有oc和kotlin那种巨大的差异。所以,我个人感觉,可以直接使用kotlin
,还可以利用kotlin中的协程等更加强大的特性。