豆瓣音乐人app的PhoneGap实践(转)

豆瓣音乐人app2011年开发时,便采用了基于原生与webapp混合架构的PhoneGap框架,直到今天。这也是目前豆瓣唯一一款使用PhoneGapapp。最近我们刚发布了音乐人appios新版,仍然保持这一架构,在原生方面的功能上做了一些增强。PhoneGap为音乐人app的顺利发布带来很大帮助,当然同时也造成了一些局限。

2149343247-0

当时如何做出使用PhoneGap的决定

我们之所以在技术选型时作出这一选择,主要有以下几个方面的原因:

开发效率的考虑

尽管豆瓣音乐人的用户对app有很强的需求,但音乐人app的定位和发展方向,当时处于不断探索和快速迭代的阶段,这样的情况意味着,音乐产品线希望使用尽可能简单的方式、占用较少的人力资源进行开发,尽快在多个平台发布,并且对于迭代的需求能够快速响应。在各种因素的权衡中,优先考虑满足上述需求。

对于原生app好还是webapp好这个问题,似乎一直有很大争议,实际上我不认为这是一个纯粹的技术问题。webapp在开发效率上的优势,原生app在性能和开发自由度上的优势,都是不言自明的,一个app是否采用混合架构,在我看来,最重要的因素还是产品定位和发展策略,如果希望尽快发布、跨平台、能快速响应可以预见的迭代,那么混合架构就很值得考虑。如果有足够的开发人员覆盖各平台、产品设计成熟度高、产品周期上可接受相对较长的开发时间,那么原生显然是更好的选择。

跨平台的考虑

豆瓣音乐人会是一个以展示内容和收听流媒体音乐为主的app,那些只有原生代码才可以实现的功能,我们需要得比较少。这意味着,如果我们采用混合架构,需要实现的原生特性与需要解决的跨平台问题会较少,混合架构的优势会被放大。

即使考虑了第一个因素后认为值得使用混合架构,如果app本身的特性不适合webapp的方式,那也会显得没有这个必要。Webapp之所以开发效率高,一方面在于html+css+js能做的事情,比用原生代码做同样的事情要简单得多,另一方面在于方便跨平台。如果app里面要实现的功能,很多都没法用html做,必须用原生代码,那这两方面的优势都消失殆尽。

实际上,就在我们第一个版本发布前不久,设计方面进行了一次review,然后对app的整体外观风格和某些功能与交互做了大幅修改。但其实只用了几天,设计的修改就被完全实现了,这样的速度对web前端开发来说当然不是什么难事,但对原生app来说却是难以想象的。

App架构与开发工作流

PhoneGap只是个原生外壳,app的内核是一个完整的webapp,需要调用的原生功能将以原生插件的形式实现,以暴露js接口的方式调用。在webapp框架的选择上,我调研了当时的一些专用于webappjs框架,几乎都不大成熟,没什么合适的,当然现在的情况已经大不一样了。由于音乐人app的规模不算大,而且在移动设备的webview中性能非常重要,我决定把一些小工具组合成一套微型框架来使用,尽可能优化执行效率。框架大致由以下小零件组成:

  • jQuery
  • iScroll4(模拟app风格的滚动);
  • js模板机制;
  • url分发与访问历史管理;
  • 页面关系与页面切换机制;
  • 基于Jsonp的带用户认证的api接口封装。

这样就简洁地实现了最小化的js框架。之所以使用jsonp的方式通信,是因为我非常希望能使用chrome进行调试,这样开发时就很方便,只需要双击本地的html文件,chrome就会成为一个完美的移动设备模拟器,我可以使用自己喜欢的任意前端开发调试工作流,这比任何移动设备模拟器都要方便得多。

有了框架,接下来只需要一个页面一个页面实现就好了,我把webapp部分作为git submoduleiosandroid的仓库都包含它,打包时使用各自的编译发布流程即可。

PhoneGap开发中遇到的问题

大致说一下遇到的印象深刻的问题。其实PhoneGap现在的版本已经有很大改进,而且主流手机的性能已经比以前好太多,现在新开发PhoneGap的话,应该会轻松很多。

css3性能问题

我们开始的设计中,有一些半透明和投影等效果,但我发现用css3实现后,会导致性能不好,这跟原生开发时可能遇到的半透明性能问题是一样的。Webkit并不如我们想象的那样有保障。后来,我们为此修改了设计,尽可能使用不透明的元素,去掉投影等效果,并减少dom复杂度,性能得到了明显提升。

像素密度问题

对于不同像素密度的屏幕,需要准备不同的图片,然后在css里面使用媒体选择器,根据 –webkit-device-pixel-ratio,分别插入密度为0.75(老android手机),1(非retina iPhone),1.5(一些android手机),2retina)的不同css,以使用不同的背景图片。只需要修改一个css文件,MakeFile脚本会自动生成其他的几个css文件。当然,我还需要保证这四套图片是存在并且正确命名的。

Mp3播放问题

iOSwebview支持mp3播放是没有问题的,但当时会有一个限制,就是如果用户没有主动操作,webview就不能自动开始播放,为它做一个workaround也就能够解决了。比较麻烦的是android的某些较老的版本,虽然支持audio标签,但是不支持mp3格式的音频,事实上它不支持任何格式的音频。所以对于这种情况,只能使用PhoneGap自带的音频播放功能。对用户而言,效果是一样的,但这增加了webapp的依赖,使webapp部分变得复杂了。

不同系统的行为差异

虽然大体上来说,iOSandroid使用的webview,其行为都是差不多的,而且由于都是webkit,样式会非常接近,几乎是自动完美跨平台。但是实际开发中发现,还是会有一些区别,例如:

  • app ready时触发的事件不一样,当然这和PhoneGap封装有关;
  • android有时候会有软键盘问题,有个插件可以解决;
  • 处理打开外部url时行为不一致;
  • 支持的动画方式有区别,对不同平台需要尽可能使用高效、硬加速的动画方式。
  • 需要为android的几个实体按键写专门的处理函数。

仍然需要编写原生代码

有的需求在webapp内无法做到,这是经常遇到的事。例如:

  • 推送消息;
  • 状态栏提醒;
  • 打开内置浏览器访问一些url
  • 绑定社交平台账号;
  • 缓存下载的图片和音乐等文件。

很多都可以找到插件来解决,现在市面上的插件比当时开发音乐人app最初版本时,已经丰富得多了,但仍然可能无法满足需求,这时就需要自己写插件来完成,每出现一个这样的需求,就意味着要为每个系统做一次原生解决方案。我们正准备把音乐人app中使用的“推荐到社交平台”的插件进行开源,提供给其他有类似需求的开发者使用。

可以移植到更多平台,但也需要一些工作

我简单试过WebOS,样式上会非常一致,但存在一些其他问题,为稳定起见,我们没有发布WebOS的打包。另外,移动版IE10已经是对标准非常友好的浏览器,但样式上跟webkit仍然有差异,不能把webkitwebapp直接拿来就用,需要做适配。感觉上又回到了桌面web开发的世界。

有趣的是,使用MacGapapp核心部分打包成Mac的桌面应用,倒是完全无痛,几乎直接就可以用。

总结

使用感觉上来说, iOS上的效果要略好于android上的效果,几乎跟原生界面没太大区别。虽然跟原生app相比,渲染速度等细节上仍然略微吃亏,但总的看来是完全可以接受的水平。

总结一下的话,我们对基于PhoneGap得到的成果是满意的,开发性价比很高。用户对音乐人app的评价也比较好。将来在产品稳定后,我们是否会使用纯原生app替代PhoneGap,现在还不知道,这将取决于产品未来的决策。希望得到什么,也就同时决定了会放弃什么,一切都是权衡的结果,框架没有银弹。

关于作者

苏丹,北京师范大学数学系毕业,现任豆瓣音乐Techleader

转载目的:用于记录保存资料和学习,感谢原作者分享

豆瓣音乐人app的PhoneGap实践(转)》上有2条评论

  1. www.fengyi6.com/about/default.asp

    夜凉如水,遥望繁星,不禁在想:有谁能错过人间的困境,擦净世间的粉尘,看透千姿百态的人生?渺渺尘世,很多人不能,既然不能,不如敞开心扉,坦然面对,把握好自己的人生,去开拓属于自己的一片天地,去寻找属于自己的温馨生活,与春天拥抱,与大自然拥抱,与未来的人生牵手。

    回复
  2. 五湖四海全讯网

    每个清晨梦醒有你,陪我同欢笑的是你,度患难的也是你,这是因为有爱我们才能在一起。情人节快乐! 每一天都为你心跳,每一刻都被你感动,每一秒都为你担心。有你的感觉真好。 美丽的你,好吗?在世界的一方我为你祝福愿你拥有一个甜蜜的情人 你的眉毛是杀死我的柳叶弯刀,你的嘴唇掏干了我的钱包,2月14日清晨,让我们一起在情海里套牢!祝你情人节快乐! 你的名字就是我在“爱的语录”里惟一的单词,你也就是我在“爱的海洋”里惟一的航班!让你我一同乘坐这航班过个浪漫快乐的情人节! 你的眼睛眨一下,我就死去,你的眼睛再眨一下,我就活过来,你的眼睛不停地眨来眨去,于是我便死去活来!祝你情人节快乐! 你悄悄说你爱我,让我紧靠在你胸前,温柔的言语轻轻拨动我的心弦,世界属于我们两个人,我们的心紧紧相连。情人节快乐!宝贝 你悄悄为我做的一切,天地知晓,我知晓!为这悄悄柔柔的温情,在滚滚红尘,我不怕红颜老褪,总在期待中度过慢慢长夜,可不后悔。祝你情人节快乐!

    回复

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

注意: 评论者允许使用'@user空格'的方式将自己的评论通知另外评论者。例如, ABC是本文的评论者之一,则使用'@ABC '(不包括单引号)将会自动将您的评论发送给ABC。使用'@all ',将会将评论发送给之前所有其它评论者。请务必注意user必须和评论者名相匹配(大小写一致)。