开发一款 SDK 需要注意哪些问题

本文详细探讨了在开发SDK时遇到的常见问题,如Java和Kotlin版本兼容性、minSdkVersion设置、依赖管理、非空处理、清晰的注释以及如何通过BOM管理和系统兼容判断来确保SDK的稳定性和易用性。
摘要由CSDN通过智能技术生成

1、版本冲突

1.1、Java 版本问题

当业务方的 Java 环境是 1.8 时,如果 SDK 是使用 Java 11 编译,则调用 SDK 相关代码的地方在编译时将会报错:

类文件具有错误的版本 55.0(jdk 11), 应为 52.0(jdk 8)

所以,SDK 在非必要情况下,Java 版本尽量兼容到最低,除非遇到特殊情况,例如 SDK 需要适配 Android 12,但 Deprecated 的 ElementType�.MODULE 标明需要 Java 9 才支持,SDK 被迫要升级 Java 版本,这种情况也能允许,但对外提供的接入文档最好明确标明最低的 Java 版本。

1.2、kotlin 版本问题

META-INF/xxxx_release.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.9.0, expected version is 1.7.1.

上面这类错误相信遇到的应该不少,Java 有一套自己的 JDK 判断准则,Kotlin 也有,Kotlin metadata 的版本来自 KGP 版本,也即意味着,当你的 SDK 使用高版本的 KGP 编译时,业务方要么编译不过,要么被迫升级 KGP 版本,这会使业务方因为升级 Kotlin 而带来其他业务的不稳定性。所以,如果非必要的情况下,尽量保持低版本的 KGP 版本,与 Java 版本类似;或是,SDK 就不要使用 Kotlin 来开发,减少影响业务方的变量。

参考文档:

  • Kotlin 填坑记之 Compatibility[1]

1.3、minSdkVersion 版本问题

组件依赖的 AndroidManifest.xml 会保留  minSdkVersion 与 targetSdkVersion, 业务方在打包时,如果 SDK(23) 的 minSdkVersion 比业务方(21)高的话,打包将会报错:

Manifest merger failed : uses-sdk:minSdkVersion 21 cannot be smaller than version 23 declared in library

如果业务方被迫升级 23 的话,将会导致业务项目机型覆盖面出现很大的问题,所以,在保障 SDK 兼容性的情况下,尽量将 minSdkVersion 调整到合适的版本

1.4、题外话

Dependency 'androidx.compose.ui:ui-geometry:1.3.0' requires libraries and applications that depend on it to compile against version 33 or later of the Android APIs. :app is currently compiled against android-32. Recommended action: Update this project to use a newer compileSdkVersion of at least 33, for example 33.

上面这个报错是在接入 Compose 依赖后报错的一个 app 工程 compileSDK 版本过低的问题,升级到 33 即可,这时我就在想了,一个依赖组件是怎么影响主工程的 compileSDK 版本的。从 External Libraries 也看不出来啥,只好看了下 transformed,惊喜发现:

图片

image.png

可以通过 minCompileSdk 来控制主工程的最低 compileSDK 版本,这算是一个依赖版本的反向应用了。

2、依赖混淆

配置 proguard-rules.pro 混淆,keep 住对外的接口与方法,混淆实现类,SDK 发布时,不带上 sourceJar,外部只能查看 class 文件,进一步增加外部观摩 SDK 核心代码难度

3、向下兼容

SDK 对外方法尽量向下兼容,如遇到必须要移除的,可提前几个版本将方法标注 @Deprecated 过期,并提供的新的调用方法,例如:

图片

image.png

  • 使用注解 @Deprecated 标注方法废弃,since 标明从哪个版本开发废弃,forRemoval 标明未来将会删除该方法

  • 注释使用 @deprecated 标注提供新的替换方法

调用效果如下,将鼠标移至方法处会提示:

图片

image.png

  • 可以使用快捷键来实现一键替换

  • 使用新的方法进行代替

4、非空处理

对外接口必须标明入参与返回值的可空与非空,避免业务方发生 NPE 问题,下面列个对比:

图片

image.png

kotlin 调用效果:

图片

image.png

  • getName 编译时不会报错,但在运行时会发生 NPE 异常

  • getAddress 在编译时会提前报错,及时发现问题

Java 调用效果:

图片

image.png

  • getName 编译时不会报错,但在运行时会发生 NPE 异常

  • getAddress 编译时不会报错,但会告警提示,运行时依然会发生 NPE(这也体现了 kotlin 非空的好处)

5、清晰的注释

一个方法最基本的注释包括:

  • 方法功能描述

  • 参数描述:@param

  • 返回值描述: @return

例如:

图片

参考文档:

  • Javadoc 规范[2]

6、版本统一

如果对外提供的 SDK 有多个依赖,并且不同版本可能会出现兼容性问题,则可以使用 Bom 来管理版本,例如官方示例 Using the Bill of Materials[3]:

dependencies {
    // Import the Compose BOM
    implementation platform('androidx.compose:compose-bom:2024.01.00')
    implementation 'androidx.compose.material3:material3'
    implementation 'androidx.compose.foundation:foundation'
}

material3 与 foundation 将会使用 compose-bom 定义的版本,未来 SDK 升级或是版本修复,都只需提供 compose-bom 的版本即可。

7、DIP 依赖倒置原则

SDK 提供抽象接口,业务方依赖接口调用,这么做的好处是,业务方面向接口调用使用简单,还能避免使用不稳定的内部实现,并且,内部实现可以进行混淆。

8、系统兼容判断

如果 SDK 有针对一些系统版本兼容的处理,则不仅仅通过 Build.VERSION.SDK_INT 来判断机型版本就够了,还要判断应用的 targetSdkVersion 版本,避免业务方使用的 targetSdkVersion 比系统兼容版本低而导致没有效果的现象。

例如 Android 12 新增的 BLUETOOTH_SCAN 权限,SDK 内部判断 SDK_INT 是否大于 Android 12,可业务方的 targetSdkVersion 并没有适配 12,清单文件也不会申明该权限,因此,该判断可能会发生不可预知的错误,所以,这里最好再做下 targetSdkVersion 的判断。

参考文档:

  • 5.2.1 一个检查更新的功能[4]

9、依赖冲突

SDK 难免会依赖一些三方库,如果业务方依赖的三方库版本比 SDK 依赖的三方库高,并且三方库兼容性差,则可能会出现 SDK 使用到三方库的一些 api 调用发生类找不到、方法找不到等异常,这似乎并没有好的解决办法,但也不是不能解:

  1. 尽量减少三方库依赖

  2. 如果三方库极其不稳定又不得不用,则可以下载其源码,更改包名,重新编译依赖,提供给 SDK 开发使用,更改包名是为了避免 duplicate class

参考资料

[1]

Kotlin 填坑记之 Compatibility: https://johnsonlee.io/2022/12/07/do-you-really-know-kotlin-compatibility/

[2]

Javadoc 规范: https://www.damo.icu/pages/javadoc/#_1-%E6%A6%82%E8%BF%B0

[3]

Using the Bill of Materials: https://developer.android.com/jetpack/compose/bom

[4]

5.2.1 一个检查更新的功能: https://juejin.cn/post/6844904193082261518?searchId=20240201160831B97DABD23F9EDF22AF8A#heading-20

转自:开发一款 SDK 需要注意哪些问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值