阿煜婚礼

阿煜是我在锤子时的设计师同事,当时一起合作搞论坛改版,我被他搞得好惨。有时候为了调整一个 Banner 投影的透明度,他会在我旁边坐上半天,0.01,0.01 地调,最后调成`rgba(0,0,0,0.08)`这家伙才满意了。

他自己的婚礼坚持不用婚庆公司,大到场地,小到一次性纸杯上印刷的图案,都是小两口自己搞定的,本来两边的家长坚决不同意俩人自己操办小型婚礼,结果实地参观了一下,愣是被俩人安排的明明白白。

9 月 15 日这天,我目睹他哭了 4 次,害得我一边录视频一边抹眼泪,都不在一起共事了,你还把我搞这么惨……

最后把给阿煜的四分钟视频浓缩成了一个一分钟的短视频,祝小两口新婚快乐!







极客时间诞生记

极客时间刚发布 iOS 版那会,好多朋友装上了一看都说「我靠,这跟原生的体验简直一毛一样啊,你们真是用 Weex 写的?」「当然是用 Weex 写的,我们差点所有页面都用 Weex 写」「为什么不用 RN 或者纯原生?」「这个说来话长……」「你们在用 Weex 时踩过哪些坑?」「等我有空了整理一篇文章发出来吧」

结果 10 月拖到 11 月,2017 年拖到 2018 年,之前一直非常忙,各种问题应接不暇、让人焦头烂额,答应了要好好介绍一下我们在开发 App 时遇到的一些问题,结果一直没有兑现。

眼瞅着公历的 2017 年已经过去了,农历的 2017 年也马上也要过去,为了不把这个事拖到农历 2018 年,特地写一篇文章出来(之前在 Weex Conf2018 有过相关演讲,地址在此,本文系对之前演讲的再加工和补充)


为什么用 Weex?

先说一下极客时间是什么。其实也可以通俗理解成是一个技术版的“得到”,不过我们也确实得到“得到”很多支持,在我们 iOS 版 1.0.6 上线 App Store 的时候遇到了审核上的困难,正好池老师跟“得到”的快刀青衣关系很好,快刀青衣拉上他们相关的研发跟我们一起分析问题,给我们传授了很多经验,最终帮助我们把这个版本顺利上线。

这是大概的界面,有视频直播、视频课、能听音频、下载音频、看专栏等等,整个APP基本上都是用Weex写的,除了ios版的充值页面,还有安卓版的播放器页面,其余所有页面都是Weex。

音频页算是整个 App 里最复杂的一个了,要记录不同登录用户 / 游客的播放进度、下载状态和进度、涉及到音频播放模块、下载模块、数据库模块和本地存储模块,还有应用级不同页面的播放状态同步、跟 H5 文章中的播放器保持播放状态同步、自定义播放进度条拖拽等,为什么安卓没有用 Weex 就是因为我们在 iOS 版踩的坑太多了,等开发安卓版的时候无论如何也要用原生实现了。

我是去年4月份去的极客邦,当时前端团队一共就两个人,一个负责大会相关的事情,另外一个之前搞过一些 iOS。做这个项目完全是从0开始,我和iOS的哥们先把iOS版做出来,其中遇到很多坑可以后面再说。

首先为什么是Weex,这个在社区里和网上有很多讨论,我也不用说的太多,就简单聊一下吧。

第一,性能优异就不用说了,每次交流大家都会说这个东西,iOS版体验还不错,Android有一些问题,这次来希望多交流,解决这个问题。
第二,我们团队的技术栈是Vue,上手简单一些。
第三,我们团队比较新,我去年4月份到了极客邦之后,前端人很少,小公司招人也很困难,用Weex性价比比较高,能很快地出东西。
第四,大家都用,社区才能火起来,当时也考虑过 RN。一对比就发现,Weex那个文档和RN一比太简单了。用Weex会有一些问题,肯定做了心里准备,但还是决定支持一下中国的框架。

第五,跟极客邦的使命契合,我们极客邦办各种各样的大会,QCon、AiCon、ArchSummit 等等,就是为了帮助中国推广开源技术,帮助中国技术人成长。我们自己做一个产品的话,不能光嘴上说说,肯定也要用中国的这些技术。

下面说一下血泪史吧。

1.5人5个月做出iOS版,当时做 iOS 版的时候我只能算半个人,另外一个人是我们的 iOS 开发 Mapple 同学,我做到一半的时候被派去做极客搜索和其他一些东西耽误了不少功夫,另外不凑巧的是还做了个手术,住了几天院又在床上躺了两个多星期。

当时选型的时候并没有太多纠结,下载了 Weex Playground,在手机上跑了一下,各种列表、demo 的大概看了一遍,很流畅嘛。池老师问我能行么?我说妥妥的啊,开发咱们这个 App 肯定so easy!于是一段辛酸的旅程就开始了……

开发人员最大的错觉就是这个很好做,到10月17号Qcon举办的时候,iOS版竟然真的做出来了,我跟 Mapple 简直欲哭无泪,现在想想简直就是个奇迹!

iOS 版上线之后大家反响还不错,但是Android版同学说你们是歧视Android吗,为什么没有Android版?

我们后来新招了一个Android的同学,也是一个半人(当时我既要管一些 web 版的东西,也要保证 iOS 版功能正常迭代),我们花了40天,做了个削减功能的安卓版极客时间,和iOS比没有下载的功能,也没有播放进度缓存等功能,因为人手的问题这些功能现在都没有上。确实安卓的进度落得特别多。我们不停迭代新功能,Android版勉强能跟上,之后还需要继续努力跟上这个。

后来Android版发布的时候,池老师老泪纵横,当时池老师跟用户们承诺11月底必须上线,不上线就拉着我和安卓的开发小哥一起跳油锅。

极客时间到目前为止有44个页面是用Weex做的,刚开始做iOS版的时候,就觉得一个播放器能有多难?后来真正做的时候发现,这个音频既要能下载,还要保存进度,不同用户在APP上登了账号,又注销了登别人的账号,切换游客身份等等,账号切换后相关的逻辑很复杂,既要更新本地数据又要控制播放器的播放状态等。

iOS 版播放器做的时候还遇到好多其他问题。进度条会闪动,一跳一跳的,还好后来更新了 Weex SDK 莫名其妙就好了。

后来做Android的时候,我就说坚决不能再用Weex做这么复杂的东西。

然后就是自定义组件和模块,我们开发和改造了20几个模块,有的是Weex本来有的,满足不了需求,我们就把 Weex 的组件代码拿过来改了改。像弹窗类,本来用Weex自带的,结果发布 iOS 版的时候赶上iOS11发布,后来发现弹窗点了之后不能回调,之后就复制粘贴 Weex 的组件自己改了一通好了。

我们做的比较复杂的模块还有audio、数据库、download、还有第三方登录、第三方分享等模块。

Webview,当时我们用 Weex 的 Webview 时有三大问题,第一个是最底部有一条黑线,怎么也去不掉。第二个是闪代码的问题,有时候加载的时候会把 jsbundle 的源码显示出来。第三个就是与H5相互通信的问题,于是我们就自己开发了Webview。

这段代码是我们 iOS的同学从Weex里看到的,但是没有公布出来。其实就是往H5发了一个自定义事件。
这个是 H5 接受 Weex 传来的自定义事件

我们和好多用Weex的团队不一样,页面会有大量复杂的通信。比如我们H5文章页的播放器跟 App 的播放器通信就比较复杂。进到 H5 文章页之后,会有一个音频播放器,点了音频播放器会发通知给Weex,调App 的播放器来播放这段音频,页面右上角会有一个全局的音频播放图标,收到播放通知以后那个图标就会动。在 App 的播放器里暂停音乐回到文章页 H5 的播放器应该是暂停的状态,这种来回通知特别多。H5里也会调登录,有时候有活动还需要调购买。

这个是安卓版的 Webview调H5,这个还比较简单,执行一下就好并没有多复杂。

不过当时开发Android版的时候,安卓开发小哥比较忙,做到最后接近 deadline 的时候 Webview与H5通信的问题还没有解决,我只好硬着头皮去看安卓的 Weex SDK 源码和相关资料。

H5通知Webview比较麻烦,H5 通知到 webview 之后,webview 还要通知到 Weex 封装的 web 组件,当时难了我很久,一筹莫展的时候隐风同学提醒我们我们可以用通知来做。于是我就用了 greenrobot 的 EventBus 解决了这个问题。

由于 iOS 版用了自定义事件向 H5 发送通知,但是安卓版是直接约定好了一个叫 geekTimeNotify 的方法供原生去调,所以在 H5 做了一下适配,调用 geekTimeNotify 会发一个自定义事件,这样就抹平了安卓版和 iOS 版向 H5 发通知的差异。

下面再介绍一下 EventBus 模块,我们的 App 不同页面之间通信比较多,从专栏列表页点一个专栏,进到专栏页再点试读文章到适度文章列表页,然后再点某一篇文章进到文章页,下面会有个订阅按钮。你点了订阅之后就需要通知到之前的所有页面这个专栏已经订阅了。页面pop掉的时候之前的那些页面这个专栏都应该是订阅状态。
还有登录了之后,有一些其它页面也需要得到通知,包括全局的播放器也要切换用户播放数据。另外就是音频的各种通知,反正就是特别麻烦,需要做一个EventBus来解决应用级的通知问题。

(图示)这是iOS代码,我们工程师也是看了Weex 的 FireGlobalEvent 的代码改的,这个就不详细说了。
这里是 Weex 端的调用方式。

(图示)这是Android的实现方式,Android小哥一直没有时间弄,我也是硬着头皮按照前端的思路写了一下。如果有什么问题,大家也可以及时反馈一下,有没有更好的办法。

还做了Video Component,这个比较复杂,目前只有 iOS版扩展了原生组件,把 ijkplayer 的代码封装成了 Weex 组件。

(图示)下面是一个原生扩展,上面用Weex做了包装,写了一个Video组件(这个组件主要是处理播放列表、网络状态变化、课程购买等逻辑)。再加上一个Webview,最后组成一个视频课的页面。

当时做这个的时候被旋转屏幕坑了一下,旋转的时候,页面的父视图转不过来,卡了好半天时间才搞定,另外一个问题是比如我想竖着滑动一下播放器调亮度,直接会触发手势返回。后来没办法就把手势禁掉了,当时连续加了很多天班,完全受不了了……

还有三段小插曲

插曲1:App 上线前贸然更新 SDK,半夜求助 Weex 团队

我们特别喜欢更新SDK,对保持最新版 SDK 有种强迫症般的偏执,没事就会上网站上去看有没有新版。
第一次出问题是从0.15升级到0.16.0,就发现列表不弹了。池老师特别喜欢拉来拉去,弹一弹,觉得挺好玩。结果准备提审那天晚上加班到到10点多突然发现列表不弹了,池老师说这个效果太不好了。后来就在群里问了Weex大牛们,大牛们特别痛快,说半个小时时间解决这个问题。临时发了0.16.1版本,升级之后马上好了。

第二次,前一段时间0.17.0出来了,我跟 iOS 开发小哥 Mapple 相视一笑,iOS和Android双双升级到0.17.0。后来就发现 iOS 版又是线不正常,列表元素里会有一条黑线。Android版支持了 box-shadow,结果升级完当时看是好的,页面一滚动那个投影投到其他元素上就消不掉了,后来问了一下Weex的大牛们,当时不太好解决,就回退回去了。
插曲2: 旋转屏的问题,这次无论如何也要自己解决

Android版 H5 页面视频全屏后再返回,Weex页面尺寸会不能重新计算,导致布局错乱。当时正赶上 Weex Conf 2018的大会快召开了,思牧他们会来北京和我们谈论大会的事情,当时就觉得有希望解决。结果见了面以后思牧说不行,现在不支持横屏,我们当时就傻了……

后来还是想了些奇技淫巧算是解决了这个问题,像这种web视频页面,之前上下两个组件都是 Weex 的,后来直接改成整个页面都是 webview就没有问题了,NavBar 和购买都用 H5 模拟然后发通知就可以了。
插曲3: 安卓版 Weex 页面不能触发 viewappear 和 viewdisappear?

(图示)这是两个Webview,本来我们用Webview用得特别爽,各种监听和通知执行地66的。直到两个Webview叠到一起时,就发现这个问题比较麻烦了,在白板小课点免费试看叠上另外一个 webview 的时候,点击购买跳登录会出现双份登录,因为两个 webview 组件都绑定了登录通知。

后来想办法,就想在页面 viewdisappear 的时候忽略掉该页面webview 的登录通知。结果在安卓下怎么也不好使,看了各种文档,也都没有说这种情况。之后在群里问了一下Weex的大牛们,隐风同学说需要在activity手动执行一下mWXSDKInstance 的onActivityResume等事件才行。

接下来再说一点感想:

  1. 文档先行;
  2. 配备好相应的原生开发,通读相关源码;
  3. 再就是过于复杂的功能,开发前要权衡、三思。

我们最开始做的时候,就没有什么文档。我在做 iOS 版的时候半路还去做了极客搜索和其他各种东西。当时人不够,正好iOS 的 Mapple同学既懂iOS又懂Vue和Weex,于是我做其他东西的时候,他就既做 iOS 又做 Weex,等我做完之后发现那些代码看不懂了,Weex 代码里面充满了像 judgeNewPlayListWhetherSameWithCache 这种 iOS的命名方式。还加了好多自定义模块,又没有列入文档里,感觉毫无头绪散落在各个地方。

(模块文档示例)后来我们专门拿出一段时间一点点把模块文档整理好了写成文档,安卓版才得以顺利开发。开发自定义模块一定先把文档写好写清楚,保证两端同时比较顺利的进行开发。

再一个是Android开发没有及时配备齐全导致进度耽误,后期Android开发就落下了。现在比较新的功能是基本同步,但之前有一些阉割掉的一直没有补回去。昨天晚上还看到用户吐槽这个事情,确实现在人不太够,疲于奔命。

对Weex的期待,首先就是社区能强大起来,这就需要在座各位一起努力。我觉得现在应该比之前好多了,最开始Weex在QCon宣布开源后我去下载,发现都跑不起来。后来开发极客时间的时候就发现工具比之前好多了,虽然坑也比较多,但还能接受。今年看的话应该更好,我觉得用的人也越来越多。然后文档资料完善起来,这个项目就会慢慢火起来。多组织交流活动,这个确实有必要。

最后感谢一下一起战斗到吐血的兄弟们,这是我们的iOS工程师Mapple,Android工程师小迪,Weex工程师旭明。他们不是没有女朋友,就是有女朋友没有时间陪,这样下去很不好。希望Weex越来越完善,让更多的兄弟姐妹早点下班!

最后非常感谢Weex对我们的支持,还有很多其他公司给我们提供了很多帮助,也感谢用户对我们比较包容。