孙涛 极客邦前端负责人
大家好,我是来自极客邦的前端负责人孙涛。今天的分享主要会说以下五个方面说起:
极客时间诞生记
先说一下极客时间是什么。其实也可以通俗理解成是一个技术版的“得到”,不过我们也确实“得到”很多支持,在我们iOS版1.0.6上线App Store 的时候遇到了审核上的困难,正好池建强老师跟“得到”的快刀青衣关系很好,快刀青衣拉上他们相关的研发跟我们一起分析问题,给我们传授了很多经验,最终帮助我们把这个版本顺利上线。
(图示)这个二维码链接到极客时间官网,扫完之后可以下载我们的APP。
![400ce016f18dc15078f7a438a7a8744c625193a1](https://yqfile.alicdn.com/400ce016f18dc15078f7a438a7a8744c625193a1.png?x-oss-process=image/resize,w_1400/format,webp)
这是大概的界面,有视频直播、视频课、能听音频、下载音频、看专栏等等,整个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 等等,就是为了帮助中国推广开源技术,帮助中国技术人成长。我们自己做一个产品的话,不能光嘴上说说,肯定也要用中国的这些技术。
下面说一下血泪史吧。
![50986794bc2c794a9220c67792eb5e4e5dfe3edb](https://yqfile.alicdn.com/50986794bc2c794a9220c67792eb5e4e5dfe3edb.png?x-oss-process=image/resize,w_1400/format,webp)
1.5人5个月做出iOS版,当时做iOS版的时候我只能算半个人,另外一个人是我们的iOS开发Mapple同学,我做到一半的时候被派去做极客搜索和其他一些东西耽误了不少功夫,另外不凑巧的是还做了个手术,住了几天院又在床上躺了两个多星期。
![3e49fdbb49f9fefed7855f48a7b11cb21a86d1c9](https://yqfile.alicdn.com/3e49fdbb49f9fefed7855f48a7b11cb21a86d1c9.png?x-oss-process=image/resize,w_1400/format,webp)
当时选型的时候并没有太多纠结,下载了Weex Playground,在手机上跑了一下,各种列表、demo 的大概看了一遍,很流畅嘛。池老师问我能行么?我说妥妥的啊,开发咱们这个APP 肯定so easy!于是一段 “辛酸的旅程” 就开始了……
开发人员最大的错觉就是这个很好做,到10月17号Qcon举办的时候,iOS版竟然真的做出来了,我跟Mapple 简直欲哭无泪,现在想想简直就是个奇迹!
iOS 版上线之后大家反响还不错,但是Android版同学说你们是歧视Android吗,为什么没有Android版?
我们后来新招了一个Android的同学,也是一个半人(当时我既要管一些web 版的东西,也要保证iOS 版功能正常迭代),我们花了40天,做了个削减功能的安卓版极客时间,和iOS比没有下载的功能,也没有播放进度缓存等功能,因为人手的问题这些功能现在都没有上。确实安卓的进度落得特别多。我们不停迭代新功能,Android版勉强能跟上,之后还需要继续努力跟上这个。
![eb47f5a34e452e1f4778389e5442e432d63f45e8](https://yqfile.alicdn.com/eb47f5a34e452e1f4778389e5442e432d63f45e8.png?x-oss-process=image/resize,w_1400/format,webp)
后来Android版发布的时候,池老师老泪纵横,当时池老师跟用户们承诺11月底必须上线,不上线就拉着我和安卓的开发小哥一起跳油锅。
![c225c7e9e9b337975f84622a5069ed00526d1d33](https://yqfile.alicdn.com/c225c7e9e9b337975f84622a5069ed00526d1d33.png?x-oss-process=image/resize,w_1400/format,webp)
极客时间到目前为止有44个页面是用Weex做的,刚开始做iOS版的时候,就觉得一个播放器能有多难?后来真正做的时候发现,这个音频既要能下载,还要保存进度,不同用户在APP上登了账号,又注销了登别人的账号,切换游客身份等等,账号切换后相关的逻辑很复杂,既要更新本地数据又要控制播放器的播放状态等。
iOS版播放器做的时候还遇到好多其他问题。进度条会闪动,一跳一跳的,还好后来更新了Weex SDK 莫名其妙就好了。
![cbbdbb91194886ab018e8555da1d77ea20997b69](https://yqfile.alicdn.com/cbbdbb91194886ab018e8555da1d77ea20997b69.png?x-oss-process=image/resize,w_1400/format,webp)
自定义组件和模块
我们开发和改造了20几个模块,有的是Weex本来有的,满足不了需求,我们就把Weex的组件代码拿过来改了改。像弹窗类,本来用Weex自带的,结果发布iOS 版的时候赶上iOS11发布,后来发现弹窗点了之后不能回调,之后就复制粘贴 Weex 的组件自己改了一通好了。
我们做的比较复杂的模块还有audio、数据库、download、还有第三方登录、第三方分享等模块。
![48683a1a2de37a6b825ef8a22fe857ca38ab0bea](https://yqfile.alicdn.com/48683a1a2de37a6b825ef8a22fe857ca38ab0bea.png?x-oss-process=image/resize,w_1400/format,webp)
WebView,当时我们用 Weex 的Webview时有三大问题,第一个是最底部有一条黑线,怎么也去不掉。第二个是闪代码的问题,有时候加载的时候会把 jsbundle 的源码显示出来。第三个就是与H5相互通信的问题,于是我们就自己开发了WebView。
![cc3aca8ab77b6156462313da5ef11417c621db3c](https://yqfile.alicdn.com/cc3aca8ab77b6156462313da5ef11417c621db3c.png?x-oss-process=image/resize,w_1400/format,webp)
这段代码是我们iOS的同学从Weex里看到的,但是没有公布出来。其实就是往H5发了一个自定义事件。
![0bf7f4309d8618c29a6965c51bae7c6a36b18ee1](https://yqfile.alicdn.com/0bf7f4309d8618c29a6965c51bae7c6a36b18ee1.png?x-oss-process=image/resize,w_1400/format,webp)
这个是 H5 接受Weex传来的自定义事件
我们和好多用Weex的团队不一样,页面会有大量复杂的通信。比如我们H5文章页的播放器跟APP 的播放器通信就比较复杂。进到H5 文章页之后,会有一个音频播放器,点了音频播放器会发通知给Weex,调APP 的播放器来播放这段音频,页面右上角会有一个全局的音频播放图标,收到播放通知以后那个图标就会动。在APP的播放器里暂停音乐回到文章页H5 的播放器应该是暂停的状态,这种来回通知特别多。H5里也会调登录,有时候有活动还需要调购买。
![47edae6a5877daeab36c50a84af97ba16cdc4ecf](https://yqfile.alicdn.com/47edae6a5877daeab36c50a84af97ba16cdc4ecf.png?x-oss-process=image/resize,w_1400/format,webp)
这个是安卓版的Webview调H5,这个还比较简单,执行一下就好并没有多复杂。
不过当时开发Android版的时候,安卓开发小哥比较忙,做到最后接近deadline 的时候WebView与H5通信的问题还没有解决,我只好硬着头皮去看安卓的Weex SDK 源码和相关资料。
![095090fecb13f81fd53aba1f45c61417184eeba5](https://yqfile.alicdn.com/095090fecb13f81fd53aba1f45c61417184eeba5.png?x-oss-process=image/resize,w_1400/format,webp)
H5通知WebView比较麻烦,H5 通知到webview 之后,WebView 还要通知到Weex 封装的web 组件,当时难了我很久,一筹莫展的时候隐风同学提醒我们我们可以用通知来做。于是我就用了greenrobot 的EventBus 解决了这个问题。
![4a237208f45c091e08fca68c9844e4641b2d7867](https://yqfile.alicdn.com/4a237208f45c091e08fca68c9844e4641b2d7867.png?x-oss-process=image/resize,w_1400/format,webp)
由于iOS 版用了自定义事件向H5 发送通知,但是安卓版是直接约定好了一个叫geekTimeNotify 的方法供原生去调,所以在H5 做了一下适配,调用geekTimeNotify 会发一个自定义事件,这样就抹平了安卓版和iOS 版向H5 发通知的差异。
![2b6958b0e1d5b1233e7082951692300487339644](https://yqfile.alicdn.com/2b6958b0e1d5b1233e7082951692300487339644.png?x-oss-process=image/resize,w_1400/format,webp)
下面再介绍一下 EventBus模块,我们的APP不同页面之间通信比较多,从专栏列表页点一个专栏,进到专栏页再点试读文章到试读文章列表页,然后再点某一篇文章进到文章页,下面会有个订阅按钮。你点了订阅之后就需要通知到之前的所有页面这个专栏已经订阅了。页面pop掉的时候之前的那些页面这个专栏都应该是订阅状态。
还有登录了之后,有一些其它页面也需要得到通知,包括全局的播放器也要切换用户播放数据。另外就是音频的各种通知,反正就是特别麻烦,需要做一个EventBus来解决应用级的通知问题。
![f3524833b4b950cf5f2741f07ec88ad2aa72f74d](https://yqfile.alicdn.com/f3524833b4b950cf5f2741f07ec88ad2aa72f74d.png?x-oss-process=image/resize,w_1400/format,webp)
这是iOS代码,我们工程师也是看了Weex 的FireGlobalEvent 的代码改的,这个就不详细说了。
![b661194a90e45eb74db031d0c859aa629ec85365](https://yqfile.alicdn.com/b661194a90e45eb74db031d0c859aa629ec85365.png?x-oss-process=image/resize,w_1400/format,webp)
这里是 Weex 端的调用方式。
![c7834a97adee8896b9ff71af2dd9c042092c9cdc](https://yqfile.alicdn.com/c7834a97adee8896b9ff71af2dd9c042092c9cdc.png?x-oss-process=image/resize,w_1400/format,webp)
这是Android的实现方式,Android小哥一直没有时间弄,我也是硬着头皮按照前端的思路写了一下。如果有什么问题,大家也可以及时反馈一下,有没有更好的办法。
![6cce9e1f242a3a8092bf2778849060f438ee943c](https://yqfile.alicdn.com/6cce9e1f242a3a8092bf2778849060f438ee943c.png?x-oss-process=image/resize,w_1400/format,webp)
还做了Video Component,这个比较复杂,目前只有iOS版扩展了原生组件,把ijkplayer 的代码封装成了Weex 组件。
下面是一个原生扩展,上面用Weex做了包装,写了一个Video组件(这个组件主要是处理播放列表、网络状态变化、课程购买等逻辑)。再加上一个Webview,最后组成一个视频课的页面。
![cba114fbf859868e70b5d29ee21956e3daaef056](https://yqfile.alicdn.com/cba114fbf859868e70b5d29ee21956e3daaef056.png?x-oss-process=image/resize,w_1400/format,webp)
当时做这个的时候被旋转屏幕坑了一下,旋转的时候,页面的父视图转不过来,卡了好半天时间才搞定,另外一个问题是比如我想竖着滑动一下播放器调亮度,直接会触发手势返回。后来没办法就把手势禁掉了,当时连续加了很多天班,完全受不了了……
三段小插曲
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的大牛们,当时不太好解决,就回退回去了。
Android版 H5 页面视频全屏后再返回,Weex页面尺寸会不能重新计算,导致布局错乱。当时正赶上Weex Conf 2018的大会快召开了,思牧他们会来北京和我们谈论大会的事情,当时就觉得有希望解决。结果见了面以后思牧说不行,现在不支持横屏,我们当时就傻了……
![c17b53a8592d92be73e2bcafff8c7db309afa065](https://yqfile.alicdn.com/c17b53a8592d92be73e2bcafff8c7db309afa065.png?x-oss-process=image/resize,w_1400/format,webp)
后来还是想了些技巧算是解决了这个问题,像这种web视频页面,之前上下两个组件都是 Weex 的,后来直接改成整个页面都是WebView就没有问题了,NavBar 和购买都用H5 模拟然后发通知就可以了。
![e0495d295fdfff5549511231569fd3b7585d0fe6](https://yqfile.alicdn.com/e0495d295fdfff5549511231569fd3b7585d0fe6.png?x-oss-process=image/resize,w_1400/format,webp)
第三个小插曲: 安卓版Weex 页面不能触发viewappear 和viewdisappear?
这是两个WebView,本来我们用WebView用得特别爽,各种监听和通知执行地66的。直到两个WebView叠到一起时,就发现这个问题比较麻烦了,在白板小课点免费试看叠上另外一个WebView 的时候,点击购买跳登录会出现双份登录,因为两个WebView组件都绑定了登录通知。
![42110863e94aaad10cd730ae750a5cb8650afd1a](https://yqfile.alicdn.com/42110863e94aaad10cd730ae750a5cb8650afd1a.png?x-oss-process=image/resize,w_1400/format,webp)
后来想办法,就想在页面viewdisappear 的时候忽略掉该页面WebView 的登录通知。结果在安卓下怎么也不好使,看了各种文档,也都没有说这种情况。之后在群里问了一下Weex的大牛们,阿里的隐风同学说需要在activity手动执行一下mWXSDKInstance的onActivityResume等事件才行。
感想和期待
![68adda4feab4e193be386d23020618deb36fe1b9](https://yqfile.alicdn.com/68adda4feab4e193be386d23020618deb36fe1b9.png?x-oss-process=image/resize,w_1400/format,webp)
1. 文档先行;
2. 配备好相应的原生开发,通读相关源码;
3. 再就是过于复杂的功能,开发前要权衡、三思
我们最开始做的时候,就没有什么文档。我在做iOS版的时候半路还去做了极客搜索和其他各种东西。当时人不够,正好iOS的Mapple同学既懂iOS又懂Vue和Weex,于是我做其他东西的时候,他就既做iOS 又做Weex,等我做完之后发现那些代码看不懂了,Weex 代码里面充满了像judgeNewPlayListWhetherSameWithCache 这种iOS的命名方式。还加了好多自定义模块,又没有列入文档里,感觉毫无头绪散落在各个地方。
![6a97d89ca481e822da6321ae09b3b6fb1ca984f9](https://yqfile.alicdn.com/6a97d89ca481e822da6321ae09b3b6fb1ca984f9.png?x-oss-process=image/resize,w_1400/format,webp)
(模块文档示例)
后来我们专门拿出一段时间一点点把模块文档整理好了写成文档,安卓版才得以顺利开发。开发自定义模块一定先把文档写好写清楚,保证两端同时比较顺利的进行开发。
再一个是Android开发没有及时配备齐全导致进度耽误,后期Android开发就落下了。现在比较新的功能是基本同步,但之前有一些阉割掉的一直没有补回去。昨天晚上还看到用户吐槽这个事情,确实现在人不太够,疲于奔命。
![0e72d352e8dada2cdf15f31ff2334146ec2c57df](https://yqfile.alicdn.com/0e72d352e8dada2cdf15f31ff2334146ec2c57df.png?x-oss-process=image/resize,w_1400/format,webp)
对Weex的期待,首先就是社区能强大起来,这就需要在座各位一起努力。我觉得现在应该比之前好多了,最开始Weex在QCon宣布开源后我去下载,发现都跑不起来。后来开发极客时间的时候就发现工具比之前好多了,虽然坑也比较多,但还能接受。今年看的话应该更好,我觉得用的人也越来越多。然后文档资料完善起来,这个项目就会慢慢火起来。多组织交流活动,这个确实有必要。
![2acdbf7c12c09bb1fa90a1e9da65b4ce3e2c4ce2](https://yqfile.alicdn.com/2acdbf7c12c09bb1fa90a1e9da65b4ce3e2c4ce2.png?x-oss-process=image/resize,w_1400/format,webp)
最后感谢一下一起战斗到吐血的兄弟们,这是我们的iOS工程师Mapple,Android工程师小迪,Weex工程师旭明。他们不是没有女朋友,就是有女朋友没有时间陪,这样下去很不好。希望Weex越来越完善,让更多的兄弟姐妹早点下班!
最后非常感谢Weex对我们的支持,还有很多其他公司给我们提供了很多帮助,也感谢用户对我们比较包容,我们会努力做好的