Part 1 | 移动端开发方案
目前移动端开发方案可谓百家齐鸣,以至于很难使用单一条件对所有移动端开发方案进行划分,在此我分成三大类来引导各位了解主要的开发方式。
- Web开发
简介:基于 Web 相关技术来实现界面及功能
a. 基于浏览器
简介:功能由服务器提供,界面的显示基于浏览器,如有道云笔记 web 版,google docs。
优点:“write once,run anywhere”,适配多个移动平台,同时功能的升级改版过程对用户而言透明。
缺点:Android 端 WebView 的性能不佳,功能受限,大量原生功能无法实现,操作体验较差。
b. 基于应用
简介:套一层原生的壳,主要功能实现基于 WebView。
优点:可以通过开发框架调用移动端 native api,可以实现 WebView 不支持的功能。
缺点:性能依旧低下,原生功能的支持依赖于开发框架。
开发平台示例:Phonegap。
- 非 Web 开发
a. 原生
简介:基于标准的 Android SDK 进行开发。
优点:可以轻松调用 SDK 提供的所有软硬件功能,性能佳。
缺点:开发速度慢,应用升级繁琐,往往需要对不同平台提供不同版本。
b. 编译
简介:直接将某个语言编译为移动平台下的二进制文件,常见的如 C++,因为 Android,IOS 都提供了对 C++ 的支持,所有界面无关的功能理论上完全可以使用 C++ 实现的。
优点:可以重用实现复杂的代码,同时编译后的代码反编译困难。
缺点:如果这个工具本身有 Bug 或性能问题,定位和修改成本很高,如果要支持 ARMv8 和 x86 的话会增大编译后应用体积。
开发平台示例:RoboVM,Xamarin(IOS),Apportable,Silver,Go,Xojo。
c. 虚拟机
简介:首先我们了解一下这里的虚拟机代表什么,提到虚拟机我们脑海出现的往往是系统虚拟机或者 JVM,但这里的虚拟机自然没有那么强大,主要功能是提供目标语言的即时编译引擎或即时解释引擎。
优点:支持热更新,拥有对应语言经验的开发者可快速上手移动开发。
缺点:大多数虚拟机提供的原生功能受限,而功能不受限的虚拟机如 NativeScript,编译生成的文件体积过大,同时如果移动端系统升级,要支持新特性需要等新的开发版本。
开发平台示例:Xamarin(Android),LuaView,Titanium/Hyperloop,NativeScript。
- 混合式
简介:上述开发方案往往是可以协同的,比如原生+Web,原生+编译,虚拟机+原生,原生+Web+虚拟机+编译,我称这些多种开发方式并存的开发方案为混合式。
优点:相互弥补对方的缺点,比如发版后频繁修改的模块可以使用 WebView 实现,大大降低发版频次,而性能要求高的可使用原生实现,提高用户体验,保密性高的可以使用编译,增加反编译难度。
缺点:未在根本上解决问题,应用的性能,开发速度,平台兼容性等问题依旧是一道难以逾越的难关。
Part 2 | 开发方案评估
我个人评估目前决定 Android 端软件开发方案选型的主要指标是以下五项:
功能实现
用户体验
开发速度
平台兼容性
快速更新的能力
Part 3 | React Native
目前三大类开发方式在这些方面各有所长。
我个人观点纯 Web 开发是未来的方向,可惜在当下,它还在胜利的道路上艰难前行着,我怀疑就算再过五年,它依旧不能走到道路的终点。
介绍这么多,那么现在也到了今天的重点:React Native。
React Native 是什么?在 Facebook 的 React Native 主页上如是写到:「LEARN ONCE, WRITE ANYWHERE: BUILD MOBILE APPS WITH REACT」
这里的「LEARN ONCE」代表着 Facebook 的 React 前端体系。「WRITE ANYWHERE」并非「run anywhere」,虽然在 Android 与 IOS 采用相同的开发语法,但两个不同的平台还是存在不同,对于部分模块还是需要两套代码,不过如果熟练掌握 React 的开发的方式,那么 Android 和 IOS 的开发就很容易上手。
我们来看一段来自 React 示例代码:
var CommentList = React.createClass({
render: function() {
return (
<div className="commentList">
<Comment author="Pete Hunt">This is one comment</Comment>
<Comment author="Jordan Walke">This is another comment</Comment>
</div>
);
}
});
var CommentBox = React.createClass({
loadCommentsFromServer: function() {
$.ajax({
url: this.props.url,
dataType: 'json',
cache: false,
success: function(data) {
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
getInitialState: function() {
return {data: []};
},
componentDidMount: function() {
this.loadCommentsFromServer();
setInterval(this.loadCommentsFromServer, this.props.pollInterval);
},
render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.state.data} />
<CommentForm />
</div>
);
}
});
React 的界面是通过调用 Class 的 render 方法将模板语言转化为 html 标签,进而通过浏览器对 html 标签的解释实现显示的目的。
从上述代码中我们可以很轻松的看出来,React 的代码编写如同堆积木一般,不同的类是不同的模块,通过组合实现功能需求。
归根到底 React Native 究竟属于哪种开发方式,拥有什么样的优势和缺点呢。
看到它支持的开发语言是JS,大家很容易认为它是 Web 开发,与 WebView 相关,事实上它并不基于 WebView,它提供了一套JS的解释器,将 Android SDK 隐藏起来,是基于虚拟机的开发方式。
那么它又有什么优势呢:
JS 是开发语言,但解释后的界面由 Android 原生视图构成,解释完成后用户实际操作体验接近原生。
使用 JS 作为开发语言,大大提高应用开发速度,同时使前端开发可以轻松接入开发。
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View } from 'react-native';
class LotsOfStyles extends Component {
render() {
return (
<View>
<Text style={styles.red}>just red</Text>
<Text style={styles.bigblue}>just bigblue</Text>
<Text style={[styles.bigblue, styles.red]}>bigblue, then red</Text>
<Text style={[styles.red, styles.bigblue]}>red, then bigblue</Text>
</View>
);
}
}
const styles = StyleSheet.create({
bigblue: {
color: 'blue',
fontWeight: 'bold',
fontSize: 30,
},
red: {
color: 'red',
},
});
AppRegistry.registerComponent('LotsOfStyles', () => LotsOfStyles);
这一段代码很轻松的实现了一个含有四个 TextView 的容器,而放到原生代码,我们首先要新建一个 Activity,然后在清单文件中注册 Activity,接着新建一个 xml 编写界面代码,或者使用 java 代码自生成界面代码,而使用 React Native 的话,上述的操作都不需要,只需要写下这段代码,并保存到项目中的 index.android.js 即可。
同时我们将这段代码和前文中的 React 代码作对比,我们可以看到语法是完全相同的,唯一的区别是 React 代码基于 html 标签,而 React Native 代码基于新的一套更贴近移动端开发的标签。
相比于其他虚拟机,它提供了 Android 原生良好的接口,对于 React Native 不支持但原生支持的功能,开发者可以轻松的添加进自己的应用。
轻松的版本更新,当对应用做好配置,新的应用打包上传到服务器后,用户应用就可以下载并在下次启动时更新。
开源,开发者可以轻松的下载下来并对特定功能进行改写和优化。
轻松的调试,JS 层代码的修改只需要在应用界面 Reload 一次应用代码即可,想比于原生繁琐的更新轻松许多。
那么它又有什么缺点呢:
极大增加安装包体积,仅显示一个界面的应用编译出来的 apk 大小已经为7.5MB。(基于 React Native 0.33)
JS 层将开发者和原生分割开了,极大增加了开发者直接进行线程调度,内存控制类似操作的难度,提高优化应用性能的难度。
依旧不是正式稳定版,开发过程中会出现一些奇怪的异常,同时不同版本之间差异较大,仍然处于快速迭代期并没有良好的向前兼容。
备注:本文参考资料 聊聊移动端跨平台开发的各种技术
本文作者:郑童宇,GrowingIO Android 工程师,原敲敲科技 Android 软件负责人。