对于移动应用开发的一些小思考

  1. 云栖社区>
  2. 博客>
  3. 正文

对于移动应用开发的一些小思考

腾斯基 2016-11-03 13:34:34 浏览4345

这是一个最好的时代,也是一个最坏的时代 -- 狄更斯

声明

以下所有内容仅代表笔者个人的思考,水平有限,必有谬误。文无第一,错了必改。

1. 无线开发团队需要解决什么问题

有一个问题我时常在思考:如果WP没有失败,现在市场占有率能在30%左右,移动市场上是android、iOS、WP三分天下的话,现在的无线开发人员,该怎么样开发一款app?我们会不会保持现在的无线开发模式,建立android、iOS、WP三个开发团队进行app的开发?
如果带着这样的假设来审视我们现在的开发模式的话,那我们一定会问,现在的开发模式是否过重?同样的业务功能,我们如何进行多端、多app的透出?我们如何能够做到我们的功能能够尽快的交付到用户的手上?
这里我不打算讨论h5 app与native app的争论,在可以预见的未来,我们可以看到hybrid app的开发会是相当长时间内的主流。在hybrid的基础上,无线开发亟待解决的问题主要是两个:

  • 开发效率
  • 动态发布

就开发效率开始,我们先简单看看有哪些跨平台开发的模式。

2. 开发跨平台应用的简单讨论

本质上,真正意义上的跨平台是不存在的。只是在具体实现上,平台的特性(异性)在哪一层被封装有所不同。举例来说,html运行环境的平台异性是通过浏览器内核予以封装的,而java则是通过JVM。

实现跨平台应用有几种可能的选择:

Code is portable

通过语言本身的可移植性,在不同平台进行编译生成机器码进行执行,代表语言有C/C++。CrossApp走的就是这个路子。

CrossApp以C++作为引擎开发语言,图形渲染基于OpenGL ES 2.0,采用MVC框架模式。现在正在整合SpiderMonkey,后续打算支持JS直接开发App(这个路子是不是有点熟?)。去年我稍微撸了一下CrossApp的源代码,貌似不少代码是借鉴cocos2dx的。
通过做游戏的思路做app,这条实现路径我表示怀疑,现在也的确没听说有爆款app的产生。

C++ -- portable code
screenshot

Immediate language is portable

通过语言运行时的可移植性,将编译产生的中间语言(IL)通过不同平台上的运行时框架在运行期编译成机器码进行执行,代表语言有Java/C#。在移动端,Mono框架算是赫赫有名,XamarinUnity3d都是基于Mono框架的产品。
这种方式的特点是能不能跨平台,能跨多少平台都是由运行时框架决定的:
Java -- portable bytecode
screenshot

C# -- portable bytecode
screenshot

说到Java与C#,这里说一段M$的一段黑历史(八卦)。在C#面世之前,Windows平台的主流编程语言是C++(包含C)。C++程序的执行效率非常刚猛,但是实在是经不住程序员培养周期过长加上本身的开发效率不足(相对而言),在接到无数程序员的反馈(吐槽)后,M$毅然拥抱Java,开始开发J++。借助Windows平台的压倒性优势,在J++中加入各种好用(不兼容)的语法开始撬动Java程序员进行开发平台迁移(通俗地来说就是其他平台写的Java代码可以在J++里编译,J++里写的Java代码不能在其他平台编译;同样的事情大家可以参考Visual C++与ANSI C++)。最终Sun公司一纸诉状告倒M$,J++寿终正寝。J++停止开发后,相关技术与理念在.net framework里被继承。C#为什么长得那么像Java也是有原因的。

个人观点:Swift的发展轨迹和C#还是挺像的,都是为了解决应用开发效率问题应运而生,大厂借助平台优势进行强势推广,开发者热情如火...最后,我们可以看看最后会怎么样。最近一直在传Swift要成为android的"first class language",这个事情我是不信的,有些事情知道就好。

DSL is portable

通过一种壳语言和自定义的解析器进行语法解析,链接到操作平台的原生API进行功能操作,这种方式可以说是当下跨平台开发的一种主流模式(也是各个大厂积极探索的方向)。相比前两种方式,这种方式的好处在于既能够绕过审核机制进行动态分发,动态分发的代码又能够拥有原生的功能与体验。这种方式大概也是所有方式中唯一可以兼顾 提高开发效率与实现动态发布 的方案。

这种方式大概的分层图如下:
screenshot
Interpreter与bridge在其中只是抽象的层次概念,interpreter用于进行壳语言的解析与原生提供的功能的映射关系(可以看作自定义的协议解析),bridge用于壳语言与原生语言的交互(或绑定)。具体到真正的实现上,基于壳语言与native接口的通信路径的选择不同,模块划分与上下层关系可能会略有差别。比如说,它的结构也有可能是这个样子的:
screenshot

讲到这里,深深地感到没有讲清楚,那就拿weex举个例子(一切以weex的presentation slides为准)。
weex的壳语言示例如下:
screenshot
webview里应该跑不起来吧。看下架构图上述代码是如何进行运转的(图是从weex的presentation slides里截的,紫色底的标注是我打的):
screenshot

这种方式的劣势有二:

  • 壳语言的语法定义比较灵活(随意),所以会明显带来学习曲线的问题。通常的解决办法是DSL使用html加javascript(加入的功能与标签都是自己做的扩展,并非真正意义上的国际标准)。
  • 目标app不接你的框架(interpreter or bridge)你就瞎,还是需要做h5的降级方案。

因为portable DSL有着同时解决开发效率与动态发布问题的好处(可能性),所以下一部分就着这点接着讲。

3. 基本概念:h5与native

h5

来到阿里之初,听到大家谈论h5的开发时,我的内心还是颇为惶恐的,因为在我印象里,h5是这个样子的:

<h1>this is h1</h1>
<h2>this is h2</h2>
<h3>this is h3</h3>
<h4>this is h4</h4>
<h5>this is h5</h5>

screenshot

过了一阵子以后,我才恍然大悟h5是html5的简称。然而又过了一阵子,我终于发现大家讨论h5的时候,没有也从来没有在讨论这个https://www.w3.org/TR/html5
那么我们一直在谈的h5到底是什么呢(答案引自知乎):

H5 最早的出处,现在已经很难说清了。

不过这也无可厚非,现在几乎所有互联网从业人员嘴上都挂着这个词。我试着总结了一下,H5 基本可以代表这么几个意思:

H5 使用手册(使用范围:中国)

以微信营销为首的广告、活动类传播页
高逼格叫法:互动营销
惯用者:广告,新媒体人、互联网运营

狂霸酷炫叼的桌面/响应式网页(模版)

高逼格叫法:@优秀网页设计
惯用者:外围设计师,甲方,“网页开发爱好者”,小白级微博主

与 Native 开发相对应的使用 web 语言开发手机 App 的技术

高逼格叫法:Mobile Web, Web App,Hybrid App
惯用者:几乎已经是互联网行业共识。产品,Native 程序员

近几年各种前端技术进化的总称……

相关概念:SPA,NodeJS,CSS 3, ES 6 …
惯用者:前端团队命名,前端招聘……

与 Flash 技术相对应的在 PC 端实现大量多媒体交互的网页技术

相关概念:Canvas,CSS 3,SVG,HTML5 Video
惯用者:Flasher,甲方,设计师

与 Flash, Unity3D 等技术相对应的网页游戏技术

相关概念:Canvas,WebGL,ThreeJS
惯用者:页游行业

与 Cocos2D 等游戏开发技术对应的手机游戏开发技术

相关概念:H5 手游,Canvas
惯用者:手游行业

HTML 5 API

惯用者:前端工程师

好吧你说什么就是什么

惯用者:接外包/私活中的前端程序员

现在我已经很习惯使用术语h5了,本文前部分提h5已经很溜了。当你发现一件事情的解释成本太高的时候,为了顺畅地沟通,最好的方式就是适应它。

native

当我们在说native的时候,我们到底在说什么?一个通俗的解释就是除去h5的其余技术部分,包括但不限于android的java、iOS的OC,还有c/c++。至此我们完成了一个完美的循环证明,无线技术分两块:h5与native,h5就是不属于native的那部分,native就是不属于h5的那部分。
循环证明的部分当然是开玩笑。“native”早期的来源当来自于“native code”,当我们在万能的wikipedia搜索“native code”时候,会发现“native code”实际指向的条目是“machine code”。关于这块就不展开了,有兴趣的直接传送门:http://www.developer.com/net/cplus/article.php/2197621/Managed-Unmanaged-Native-What-Kind-of-Code-Is-This.htm

当下我们在移动应用开发中提到的“native”当出自“native app”,即指向系统提供的原生能力的使用。如果说我们当下日常使用中对于“h5”已经意义宽泛化了的话,那么我们可能对“native”可能已经意义窄化了。很多时候,我们在谈“native”的时候仅仅是在谈“native UI”。

回归到正题,这里既然需要谈一下portable DSL的开发方式,那么就说下我对“native”在这种开发方式下的理解:本质上portable DSL提供的是一种能够通过解释执行的语言,通过解释执行的语言赋予这种开发方式以更高的开发效率与定制化能力;“native”在其中是指为了完成底层框架的一种需要编译才能获得的系统能力。
这种开发方式在PC时代并不罕见,不少ERP软件(由于ERP软件的特殊性,所有企业几乎都需要进行定制化地二次开发)提供的都是一个基础框架,实际在企业上线前都需要通过脚本语言去二次开发自定义的操作界面与业务流程。

下一部分就是今年北京QCon基于portable DSL的移动动态化方案的分享。

4. Weex、ReactMix、WeX5、LuaView

今年四月去北京参加QCon2016,移动开发中很大一块集中在动态化方案上(另一块是直播,今年真是直播大年)。
在动态化方案上,一共听了4个讲座:
Weex: 移动端高性能动态化方案 (提取码:oz1nI4)
老树开新花: LuaView - Lua在聚划算App动态化中的应用
Hybrid app走向轻混
ReactMix: HTML+CSS+JS写ReactNative

Weex与LuaView

Weex与LuaView都是阿里的产品
Weex算是React Native的竞品:据说Weex中借鉴了不少Vue.js的语法,所以说是Vue Native,问题也不太大。
LuaView用的是相对古典的思路:Lua在游戏app里的应用是非常广泛的。在过去的很多年中,也有不断的尝试规模化地用于应用类app的开发中。LuaView在其中算是走的比较靠前的(具体内容可以翻阅PPT)。
两个方案的优劣我就不评论了(水平不够),只想着重提两个点:

  • 壳语言的学习和使用成本是重中之重
  • 工程化的能力决定一切

ReactMix

ReactMix是基于RN的开发,补齐了css特性,实现“write once,run anywhere”。
github: https://github.com/xueduany/react-mix
这个分享是接着Weex的分享的,思路有些不同。感兴趣的同学可以搜一下知乎,可以看到一些相关讨论,链接我就不放了。
对于RN,我比较赞同的是两个理念:

  • “learn once, write anywhere”
  • virtual DOM

对于ReactMix,我倒是有两个疑虑:

  • “write once, run anywhere”的愿景很美好,但是却很难。当能花80%的平台差异性可以通过20%的努力来完成时,后面的20%可能需要80%的努力来做,可能还到不到。换句话说,灵活性与一致性不可兼得
  • DOM和CSS基本是性能杀手了,支持CSS全特性其实是在打破RN本身的假设

WeX5

WeX5其实就是基于cordova进行改造与封装,官网地址:http://www.wex5.com/wex5/
分析技术也并不复杂,有三个特点:

  • 封装了微信的sdk,所以开发的应用页面可以无缝跑在微信里(可以将WeX5看成是微信生态圈里的产品)
  • 实现了一个开发工具链,可以通过拖、拉、拽的方式完成WeX5的界面开发
  • 主要优化集中在h5端,对于native的功能依赖不高,对于密集交互型的场景和渲染密集型的场景考虑不足

这种思路算是比较古典的开发方式了,但是的确像分享人所说的

  • 其他技术的页面都没法在微信里跑(只要你没适配微信sdk)
  • 比较适合小团队冷启动(因为不用安装app,只需要微信扫码)

技术上的亮点稍微有些乏善可陈。

WeX5的结构
screenshot

写在最后

移动平台的web化是趋势,当下的问题,我们能看到,就需要努力去通过技术变革的手段去解决。现在正处于技术变革的时代,变革意味着机会。也许我们现在正处在一个移动开发最坏的时代,也许我们现在正处在移动开发最好的时代。