起因
近期由于 UPYUN 的图片服务频繁出现低级问题(具体啥问题就不列出来了, 反正影响到我们的业务逻辑), 我们决定整体切换到阿里云图片存储服务. 接入阿里云的过程中, 我们又发现一系列让人恼火的问题, 干脆总结一下解决方法, 顺带吐个槽
问题
依赖
问题始于我们 App 的网络库与阿里云 SDK 的依赖冲突上:
- 我们的 App 使用 Retrofit2 实现网络请求层, 而 Retrofit2 依赖于 okhttp3 以及 okio
- 阿里云 SDK 的网络请求依赖于 okhttp2 + okio, 并且无法替换
由于 okhttp2 和 okhttp3 不兼容, 我们必须同时保留对两者的依赖
Proguard
同时保留 okhttp2 和 okhttp3 带来了新的问题: Proguard
由于两个库都包含了一些同名类, 在编译时这些同名类会产生冲突导致编译失败
解决
方案
在狠狠吐槽阿里云 SDK 后, 我们决定将它抛弃, 毕竟不能为了它而强行降级我们的库.
但是我们仍然希望使用阿里云图片存储, 怎么办? 自己实现!
实现
对于我们的业务来说, 目前 SDK 最重要的事情就是帮助生成鉴权信息, 其他功能于我们(暂时)都没啥作用.
根据阿里云 SDK 的文档以及阅读源码, 我们了解到了阿里云的 STS 鉴权机制. 剩下来的就是自己实现了.
具体的代码没有必要贴出来, 毕竟阅读文档 + 参考源码就能实现. 这里列一下去 SDK 的具体过程吧:
- 分析业务逻辑依赖的 SDK 接口
- 实现自定义类 AliyunUtils, 代理对 SDK 的依赖
- 将业务逻辑中所有对 SDK 的依赖重定向到 AliyunUtils 中, 这一步解除了业务代码与阿里云 SDK 的耦合
- 修改 AliyunUtils 的实现, 不再代理 SDK 接口, 而是自己实现鉴权等方法
- 删除阿里云 SDK, 至此, 我们的 App 不再依赖阿里云 SDK, 同时也去掉了对 okhttp2 的依赖
思考
阿里云 SDK 使用优秀的网络库是一件极好的事情, 毕竟 okhttp 好用, 可以提升 SDK 开发效率. 但是开发者们忽略了几个问题:
- 作为一个优秀的网络库, okhttp 可能早已存在于需求方的依赖列表中
- okhttp 是在不断更新的
- 阿里云 SDK 里并没有提供设置自定义网络库的接口
言尽于此, 想必大家心里有数了, 这个 SDK 的问题不在代码质量而在设计思路, 我们以后在工作中务必引以为戒.