本文是我的好兄弟潘永强分享,现就职于阿里巴巴,点击【阅读原文】欢迎关注他的博客:
https://blog.csdn.net/ieyudeyinji
有要阿里内推的同学,可以直接去阿里官网看好职位,找老潘给大家内推。
这几天在做公司内部的分享sdk要添加一个新功能,在自己阅读代码时,发现了很多问题,另外之前也有用户反馈了一些问题,自己只是做了一个维护,这次在做新功能调研时,发现了微信的很多细节做的挺好,整体在这里分享下。
这里我们假如说接到公司的一个业务需求,要我们实现一个分享的sdk,提供给第三方,让他们可以更加方便快捷的接入到我们的平台,公司要让你做,直接就让你什么时候能做出来?你会怎么办?我们以一个安卓开发者,但没有做过此功能的同学在此场景为例。
老板才不会考虑你担忧的细节,它就要结果嘛,而我们需要做的事情是很多的,最可怕的不是老板问你什么时候做出来,最可怕的而是你不知道从何处下手。
其实面对未知的问题一点也是不可怕的,我们要有自己的做事套路和方法,我分享下我会如何做这件事情的。
需要找产品经理确认清楚,这个分享sdk到底要包含哪些功能
确定好了后,看下现在外面有没有现成的一些产品包含这些功能,如果有,是否与我们的产品需求类似,如果类似,是否可以参考他们的实现方案;如果没有现成的方案,那么就自己设计;
他们的实现方案有什么优缺点
确定在他们的方案基础上,进行再次设计
确定了设计方案后,再去将方案细化
确定方案细节后,可以先给出一个技术方案的报告,和团队的小伙伴和自己的leader分享下自己的方案
方案通过后,根据自己的实际开发情况,确定工期
确定工期后,将需要的时间告诉自己的老板
开发开发,定期汇报进度
测试,bug fix
上线
上面是自己的想法,下面我们基于上面的想法,进行实际的操作
确认需求
为什么第一步要产品经理确认细节,因为很多产品经理或者是老板,在提出需求时,都只有一句话,如果没有确认清楚,自己就盲目的开发,坑的是自己,最后返工,各种加班,是要自己背锅的,在同产品经理或者是老板确定清楚后,至少要在群里,最好是能落地成一个文档,这是一个证明,虽然很多时候老老板或者产品经理喜欢后期改需求,但是前期定下来的需求要板上钉钉,这样后期他们修改时,造成工期的延迟,也不是开发同学的责任,我们是有证明的,并且是没有争议的.
进入正式的阶段:和产品经理确认需求如下:
开发可以分享文本,图片的分享SDK给第三方使用
最好能和国内的一线APP功能对标,像微信。
有了这两个细节,我们就开始第二个步骤了
参考成熟产品
第一步产品经理也提到了,要类似于微信的分享SDK,我们先不谈论实现,我们还是要知道微信是如何实现的,现在的产品经理,也是比较懒惰的,也就是说类似于微信,像很多的产品细节也都不去考虑,直接让开发同学去看,你看到的边界情况,很多是他们没有考虑到的,你还能说什么,也就是自己上呗,那我们就去看下微信的实现,正常来讲,我们手里也有其他的应用,可以分享到微信的,我们先正常的体验下:
2.1 使用三方APP,进行正常的操作使用
以友盟为例:友盟有自己的分享sdk的demo,并且是集合多家的,而且分享的各个类型(文本,图片,链接),所以就直接用他的这个demo即可,登录友盟,下载友盟的分享demo的apk
打开apk,尝试各个类型的分享,以链接举例:发现打开友盟分享链接到微信时,微信会先loading一下,然后才会跳转到选择好友的页面,选择一个好友后,就直接分享了出去,分享后,会问你,是留在微信,还是返回到友盟?我们都操作一下,留在微信的话,微信会直接跳转到首页,返回到友盟,会结束当前页面,返回到友盟。
这个是初步看到的样子,也就是正常分享的样子,但是作为开发者,如果只是看到了这么多,你就去接下来考虑评估工期,那你真的是想多了,在我们真正的开发前,要考虑的事情是很多的,你要知道,正常情况,其实只是占日常开发工作量的20%,更多的是那些异常情况的处理.
2.2 且慢,看看异常流程再下结论
我们再去接着考虑,刚刚看到了正常分享到微信的情况,我们现在要细想很多其他的情况了
手机上没有安装微信? 是否可以分享呢? 即是否支持网页分享呢
手机上安装了微信了,但是微信没有登录,能正常支持分享不?
微信登陆了,但是账号被踢出了,是否还能正常分享
把微信切到后台,先查看其它app的信息,是否在最近使用的app中,看到这个分享的页面呢?
假如在分享的过程中,把微信切到后台,再返回三方应用,会怎么样?再次分享到微信呢?
假如分享到微信时,我正常和其他人聊天,此时分享到微信,分享成功后,会不会影响我和其他人的聊天页面被关闭掉?
……..
是不是突然感觉好多问题冒出来了? 你只是看着正常流程,那么这么多情况,是不是没有考虑? 有时候老板的一句话需求,能让你忙活半个月,有时候老板也会提出一些无厘头的需求,比如说让你画一个方形的圆……
所以评估工期要慎重,那些年加的班,很多情况是自己坑自己的.
2.3 把上面提到的各种问题都分析下
a、手机上没有安装微信? 是否可以分享?
看了下,微信应该是不支持分享sdk网页内分享的,所以这个可以先忽略,也就是说需要提供方法,告诉三方APP,是否安装了微信
b、手机上安装了微信,微信没有登录,是否能够正常支持分享?
在手机上操作下,发现微信是可以的,有这个功能体验会好很多,可能有些用户还是没有登录的,但是发现微信的登录界面,不同于正常微信的登录,正常微信的登录,是可以登录的类型很多的,这里也就是最精简的账号登录,没有找回密码等,也就是这里的登录是可以特殊处理的,等登录成功后,展示好友的列表,同之前的正常登录的路程
c、微信登陆了,但是账号被踢出了,是否还能正常分享?
这个在手机上操作下,便可知,微信在此时,提示了一个特殊的错误信息,就没有然后了
d、把微信切到后台,先查看其它app的信息,是否在最近使用的app中,看到这个分享的页面呢?实际操作下,发现在最近使用的APP中,是看不到我们的分享页面的,这个实现有点奇怪,不过多想想便知道微信为什么这样设计(个人猜测是技术原因: 如果先查看其它app,这里的分享信息还在显示,在我们继续分享后,需要在历史中不再显示这个分享的页面,安卓上,如果task的root activity,没有设置为不在历史上显示,在task的上面的activity设置是无效的,所以微信这样做也是没有办法的)
e、假如在分享的过程中,把微信切到后台,再返回三方应用,会怎么样?再次分享到微信呢?
如果返回到三方的应用,再次分享,如果分享不同类型的信息,看到是新的信息,说明这个是要刷新的
f、假如在分享的过程中,back按键返回三方应用,会怎么样?
此时发现是会提示分享取消的,说明back按键是要特殊处理的
g、假如分享到微信时,我正常和其他人聊天,此时分享到微信,分享成功后,会不会影响我和其他人的聊天页面被关闭掉?
其实在启动三方分享时,查看最近使用就可以看到,微信显示的是两个最近使用,说明微信开启了多Task
当然还有其他的细节,大家可以自己看下…..
2.4 看下他们的demo,是如何实现的
看到这里,你会不会觉得原来没有这么简单,他们在细节上有很多的处理的
那根据我们上述的分析,我们再去看下他们的分享SDK中的demo是如何对外提供的
他们的demo,大家可以自己看下
微信资源中心,代码我就不贴出来了
看到他们的操作步骤
先将自己的包名和签名,在微信的开放平台进行申请
申请通过后,会有一个APPID
查看微信的demo
-在代码中接入代码的流程
Factory创建API,需要APPID
构建request,将信息填入
api发送Request
需要返回结果的,拷贝demo中的结果页面,到自己的包下面,根据他们的说明,可以添加Toast的提示信息
看到了代码的调用流程,下面看下sdk的实现的细节
看到他们的request的设计细节,就是将请求信息组装到一起
api发送时,将数据填充到请求的Intent中
启动微信的WXEntryActivity,将信息填写进去
启动的Intent中,填写了两个Flag,将十进制的Flag转为十六进制的Flag,再对应下安卓的源码,看到是不常用的两个Flag,和我们没有太大的关系
看下回调的activity是 singleTop的设计,在onCreate时,构建API,交给API去处理
API在处理时,设置了回调,处理onReq()和onResp()即可
分析别人的设计
2.5.1 微信分享SDK的设计
到这里我们知道了SDK的设计方式了,用示意图总结下
看到这个,我们大致知道他们外部的实现了,就是已经解决了了SDK的设计问题了,下面就要想想他们内部如何设计了,因为微信的源码肯定是混淆过的,我们只能分析+猜测了
2.5.2 分享SDK对应的微信分享的设计
在上面我们提到了很多分享一些异常情况中,微信的处理
再加上看到微信的分享的sdk的入口的activity为WXEntryActivity(com.tencent.mm.plugin.base.stub.WEEntryActivity),这里我们要开始猥琐点了,要开始反编译微信的源码了,这里推荐使用 jadx
源码肯定是混淆过的,这里我们也只是看下一个基本的,反编译后,看下AndroidManifest.xml的WXEntryActivity,看到有一些特殊的设置,是excluseFromRecent,不了解的同学,google下,能够看到这个标志位是说如果是taskRoot时,当前task的activity都不会显示在最近使用中,哈哈哈,得来全不费功夫,找到了一个关键的知识点,这个一会儿我们要用到.
现在要了解下安卓的基本知识了,微信的WXEntryActivity在启动时,并没有设置为INTENT.ACTIVITY_FLAG_NEW_TASK, 所以这个启动的task与三方APP相同,但是启动后,在部分手机上能够看到,按下最近使用时,微信的分享页面,却并不在三方APP中,这说明,他们中间切换了task,因为切换了task后,将新启动的task,设置excluseFromRecent=true,才能不再最近使用的task中展示,另外也需要new_task,不仅如此,还有clear_task或者clear_top等(此处可以看下单纯设置new_task的缺陷,会导致应用是因此而启动时,再次启动时,便只是将APP 放置到前台,不会启动对应的activity,这是一个坑,要注意的)
切换task,可不止这些信息,因为在查看最近使用时,如果你已经打开了微信,可以看到,在最近使用里面室友两个,说明分享的task也不是微信的主task,所以我们还需要把从WXEntryActivity启动分享到好友的页面的Activty的AndroidManifest.xml中配置一个taskAffinity,这样便不在主task中启动微信了,达到了预期的效果.
这些是从分享SDK到微信的流程.
点击分享后,需要将结果回调给三方的Activity,这里就比较简单了,如果选择留在微信,通知三方结果(此处记不清楚了,读者可以自己测试,可能没有通知,因为担心三方APP另外启动其他的页面做操作,影响体验),然后启动微信的主Activity,切到主要Task,如果用户选择返回三方,通知三方APP的结果,finish当前页面即可
微信内部的流程猜测如下,部分情况未验证,读者可亲自验证(此图为猜测图,Activity名字为个人所命名,不代表实际的Activity)
微信内部分享流程猜测图
还缺少三个小点:
启动未登录的情况,可以先启动前做判断,如果未登录,将要跳转的页面信息,存储下来,登录后,再跳转回来即可
其他设备上登录,看微信之前的方式,是直接提示错误了,不能继续分享的流程了
用户签名不匹配的情况,个人没有进行测试,此情况可以在分享点击时进行提示,或者在从WXEntryActivity启动时,进行网络请求一致性的校验,如果不一致,直接回调到结果页错误即可
衡量方案优缺点
缺点目前看到的只有一个: 在正常分享的过程中,如果按下Home按键,便不能再次分享
在轮子上造好轮子
确定在他们的方案基础上,进行再次设计,对于新开发的功能,其实可以完全照搬过来
方案细化
此时可以将细节设计出来,上面分析的设计方案,没有提到其他的一些,比如说,分享sdk要有版本,分享sdk的版本如何与微信的主版本的匹配,版本如何规划等细节
给出技术方案
确定方案细节后,可以先给出一个技术方案的报告,和团队的小伙伴和自己的leader分享下自己的方案,这个不用多讲了,最主要的是让团队确定是否可行,以及是否有更好的设计方案,还有假如这样设计的话,会给现在的代码带来多少可行性的影响。
还有一个问题是,如果大家没有异议,后续遇到了方案不可行,也就不用自己全部承担此责任,因为团队都认为是可行的,大家对于自己遇到这样的问题会更加理解.需要团队其他成员帮助时,大家了解的更多,也会更加容易上手.
给出Timeline
确定工期后,将需要的时间告诉自己的老板
工期要给自己留点buffer,否则,受伤的是自己;
还有,如果他们需要紧急上线,有buffer;
自己不会那么紧张,而且还有可能团队会给自己支援
开发并定期汇报进度
不要老是让老板问自己的进度,要学会自己上报进度;经常被老板询问,也是一件很不开心的事情,自己的思路还会被打断
测试,bug fix
上线