前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SDK开发的一点点心得 | 经验之谈

SDK开发的一点点心得 | 经验之谈

作者头像
逮虾户
发布2022-03-06 09:43:10
5150
发布2022-03-06 09:43:10
举报
文章被收录于专栏:逮虾户逮虾户

theme: smartblue

前情提要

各位大佬大家好,我刚从枸杞岛团建完回来。这篇文章的大纲和一部分内容还是我在枸杞岛上编完的。接下来先给大家看看我们团建的枸杞岛风景吧。

image.png
image.png
image.png
image.png

因为之前把一些老底都交待完了,手头上感觉没啥新的文章素材可以和大家聊的啦。而且最近一直都在写一些sdk相关的东西,所以打算给大家分享一下经验,从sdk设计的角度给大家水一篇文章。

正文

首先我手头上负责了三个sdk:支付,推送,debug组件,其中尤其是推送和支付非常的难搞。因为他们本身是业务的一部分,如果你把他们当做一个大礼包提供给别人使用的情况下,估计会被接入方骂死。

我觉得我的sdk设计的也不算是特别优秀吧,但是我觉得还是有些东西可以稍微分享点给大家的。有时候多和同行之间沟通交流才能获得更好的成长吗。

下面我会根据几个不同的小点给大家聊一聊我认为合理的一个sdk应该是怎么样的。

少依赖

我经常碰到的一个问题就是,使用方会说你们的sdk是一个大礼包啊,为啥会有这么多的仓库依赖啊。我明明只用了你们一小部分功能,但是因为用了SDK,所以被引入了一大推的依赖。

举个例子网络库,数据埋点,图片库等等一大堆东西都会被依赖进来。所以在没有使用的情况下,sdk所需要的就是用最小的依赖关系,来完成你所需要的功能。之前有个大佬对这部分有过分析。

对 Android SDK 开发的一些个人心得

我这边更多想给大家的小建议是这样的,有时间就多跑跑gradle dependcies命令,然后自己合理的分析下那些东西是需要的那些东西是不需要要的。

同时合理的使用设计模式,就类似我上篇文章介绍的异步责任链一样。这些东西可以帮助你在后续的迭代中,更好的维护你的代码。

另外就是可以通过接口的方式将图片,网络库,埋点这些库加载到sdk内。另外就是这部分我觉得也没必要写的特别极致,如果你像我一样是个对内的sdk,你直接引入这些库也是非常河里的。

当然并不一定要一步到位,可以拆开打散成多个阶段,每个阶段删除掉你觉得没有用的依赖,否则一次性不仅风险高,而且也太难了。

多模块

我在开发这些sdk的时候,考虑的是通过最简单的动态化能力,把这些三方sdk打散,之后通过适配器的形式把他们的共性聚合到一起。通过多个Module的形式提供给使用方自行排列组合,比方说A接了其中的12两个,B接了其中的13,接入方可自行选择自己需要的东西。这样就可以避免大礼包代码的出现,同时也可以丰富业务的接入能力。

同时就是很多三方库在设计的时候,都会考虑把功能进行更细力度的拆分。举个例子,retorfit就有很多adapterconvert的子module,之后使用方也可以通过自行组合的方式去对其进行使用。

如何拆分粒度呢?我最近的思路是这样的,一个能组合的库起码要有三层。

  1. 接口层 这部分我只负责定义所有三方的共性相关,从面相对象上来说,我们可以通过依赖倒置的形式使用他们的父类。
  2. 业务层 这部分我要调用下原始定义的接口层,之后通过一些动态化的方式(最简单的方式就是通过反射或者服务查找(SPI)相关的方式)获取到具体的实现类,完成抽象类到实现类之间的转化调用。
  3. 三方sdk层 这部分就和retrofit的adapter一样了,我们只要在这里对抽象接口进行实现就好了。

如果你的SDK内还有一些ui相关的,你可能还需要提供一份ui定制的能力给到使用方,这样如果业务方有对页面修改的需求,只需要他们自行调整即可了。

加开关

SDK也不是一成不变,在一个持续迭代的过程中,当一个相对来说比较重要的功能上线的时候,最好是能通过abtest的方式,配置一些线上的灰度策略和回滚机制,让你可以更稳妥的把你的新增功能推到线上去。

举个例子,我们之前在替换新旧支付sdk的时候,采取的策略就是两个版本同时存在,之后通过线上灰度测试,在新版sdk稳定之后,再把整体sdk替换到新版本上。

有什么好处呢? 首先可以观察下sdk是否稳定,之后有没有crash问题还有会不会影响到原来的流程上。如果有问题则直接线上开关关闭。

单一出口

支付的上一个负责的同学,在调用支付的时候定义了非常多方法。比如说不同参数调用不同的方法,activity或者context或者fragment都使用不同的方法,跨进程使用另外一批方法,然后还要声明页面回调onActivityResult等等。

这有什么缺点呢?

sdk的使用方要自己根据不同的参数来决定不同的函数调用是什么,那么当你的sdk要开始拓展参数,或者别的什么的时候,你就会发现WTF,这个也太难改了吧,业务方可能就会向你的上级直接投诉你的代码质量了。

在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。这个技术由 Christopher Strachey 以逻辑学家 Haskell Curry 命名的,尽管它是 Moses Schnfinkel 和 Gottlob Frege 发明的。

这部分设计上,我的看法就是单一变量参数,然后在sdk内将主动判断其他的额外条件,比如进程回调,参数的增减,以及回调结果等。

同时越少的代码调用,也就意味着sdk内可以为所欲为,即时我内部做了再大的改动,只要我没有变更过调用方法的逻辑,那么业务调用方就不会感知到这部分相关的。

数据说话

当我们跑完一个测试流程发现都没有问题,之后我们发布线上之后,如果线上问题反馈,我们应该怎么办呢?

sdk内还是要有一套专门排查线上问题相关的埋点,以及关于sdk回调结果的埋点的,这样我们就可以通过用户所提供的id相关的数据去反向查找下用户相关的埋点,之后根据最后的埋点结果定位用户所发生的实际问题。

而另外一些数据也可以反向证明我们对于这部分sdk的优化如何,也可以帮助我们完成我的kpi指定计划。

与时俱进

现在项目内已经加入了协程的依赖了,所以对于sdk来说,你只提供了一个异步回调给到使用方也是不满足诉求的。

所以在原来出口方法的基础上,我额外添加了一个协程的依赖库,将异步函数改装成了一个suspend,这样有需要的使用方以后就能直接用这个函数获取到结果,之后更简单的写代码了。

同时因为是一个新增的仓库,所以也不会造成其他没有引入协程项目的困扰。

可调式

正常情况下一个sdk提供给使用方的都是一个aar,如果在接入的时候发现一些难以调试的问题,如果我们一个个aar的版本发布,会严重影响你的开发进度,所以一个合理的混合开发模式,可以帮助你减少这方面的困扰。

小贴士 我之前的文章有介绍过compose build 同时我之前写的一个插件也可以帮助大家更简单的做这项工作。传送门

更简单的接入方式

上面说的只是相比较于sdk方面的设计了。我其实在接入的时候打算让别人能更简单的接入,如果能根据不同的App自动生成不同的代码则是最佳了。

作为一个内部sdk,由于要降低sdk对外部的依赖问题,所以自然而然就会不方便初始化,但是写得多错的多的道理大家都懂,所以如果这部分接入也可以由代码自动化生成,那么就可以解决很多痛点问题。

这里我还是按照我之前写推送sdk的经验,采用Android厂商推送Plugin化的方式。动态生成了埋点类和微信支付回调的activity,接过的知道要根据应用包名写一个自己的回调接受的activity

为了紧随时代的潮流,这次还是用kotlinpoet生成的kt代码,也碰到了一些奇奇怪怪的问题。比如kotlin的Map类并不是java的Map吗,kotlin的String也和java的完全不同。

同时,由于plugin内是知道当前接入方的applicationid的,所以我们可以自己把匹配上的applicationid的依赖有plugin来自动导入添加,同时完成项目内依赖的版本清洗工作,让对方开发人员尽量不感知到我们的aar

TODO

我这边在添加埋点代码的时候增加了一些简单的逻辑判断,如果项目内有微信埋点库依赖的情况下,才会自动生成这部分逻辑,如果没有找到依赖的话就会不生成,避免类引用不到所导致的异常。

但是我这边使用的是gradle configuration里面的allDependencies方法,而这个方法是不会把传递进来的依赖进行判断的,所以还是有个小漏洞在这里的。

有了解的大佬可以在地下留言给我,让我拜读下,如果是kotlin最好了,感谢,感谢。

结尾

这篇文章主要内容现在都只是我的一些感慨和经验之谈,如果你认为有什么问题,欢迎各位大佬在评论区展开讨论啊。

还有一点就是因为我之前也是一个sdk的使用方,其实我对于使用方的诉求其实是有些了解的。所以我在封装的时候就会尽量把一些我不想写的东西,或者我之前用起来不方便的东西规避掉。

开发过程中我也会加入一些我自己的思考,比如我觉得一些东西我可以自动生成,我就会去自动生成这个类,这样其实对大家来说都会更方便。思考多了,其实很多东西你都能玩出各种不同的花样的。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021/04/19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • theme: smartblue
  • 前情提要
  • 正文
    • 少依赖
      • 多模块
        • 加开关
          • 单一出口
            • 数据说话
              • 与时俱进
                • 可调式
                • 更简单的接入方式
                  • TODO
                  • 结尾
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档