App开发
一 开发方式
原生开发(Native App)
指在Android、IOS等移动平台上利用官方提供的开发语言、开发类库、开发工具进行App软件开发。其中Android是利用Java、Eclipse、Android studio;IOS是利用Objective-C 和Xcode进行开发。
优点:
- 原生APP最大的优势在于性能,能够快速运行、支持大量图片内容以及一些动图等,在使用设备提供的接口方面也更加快捷。
- 可实现的功能更多,可访问设备提供的所有功能。
- 兼容性更高,经过精心设计与调试后可以达到更加理想的效果。
- 在App Store审核期间会进行检测,确保无害后上架,用户无需担心其安全性。
缺点:
- 成本高,开发时间长,需要的开发人员过多,Android和iOS需要各自单独开发,无法跨平台兼容。
- 需要将App提交于App Store,这意味着客户能否下载使用,取决于客户手机应用商城是否准许。
- App Store审核周期较长(首次提交最快5-7天,再次提交最快1-2天,指单次审核,没有被驳回的情况),无法追求快速更新。
- 不同用户可能使用不同版本的App,提供所有版本的支持较难。
混合开发(Hybrid App)
Hybrid App指半原生半Web的混合类App。看上去类似Native App,但访问的内容是Web。
混合应用程序让开发人员可以把HTML5应用程序嵌入到一个细薄的原生容器里面,集原生应用程序和HTML5应用程序的优点(及缺点)于一体。
优点:
- Hybrid App的优势主要在于开发成本低,一套代码可兼容多种平台,不需要两拨人进行开发。
- 更新和部署比较方便,每次升级版本只需要在服务器端升级即可,不需要上传到App Store进行审核。
缺点:
- 性能方面不是很稳定,其加载/运行速度太过依赖于网络环境,因其原理在于将Web嵌入进App。
- 对于不同机型的兼容较差,在不同比例的屏幕上的表现有一定差异。
- 功能/界面的定制性较差,能够实现的功能有局限性。
对比
原生开发 | 混合开发 | |
---|---|---|
开发周期 | 开发周期远长于混合开发,Android和IOS都要各自开发 | 开发周期较短,一套代码兼容多种平台 |
性能 | 运行速度快,在调用设备提供的接口时有性能优势 | 数据需要全部从服务器调取,网络占用高,缓冲时间长 |
兼容性 | 兼容性高,一般不会出现闪退的情况 | 兼容性一般,在最新手机系统上不能很好的兼容 |
定制性 | 可访问手机所有功能(如GPS、摄像头),可实现功能最齐全 | 功能、界面无法随意更改,想增加功能困难 |
跨平台性 | 无 | 优 |
维护更新 | 较为复杂 | 代码维护方便、版本更新快 |
上线 | 需要上传到App Store进行审核,需要注意App Store内容限制 | 每次升级版本只需要在服务器端升级即可 |
二 混合开发技术
1 uni-app
uni-app
是HBuilder
母公司DCloud
推出的一个使用Vue.js开发所有前端应用的框架,开发者编写一套代码,可发布到iOS
、Android
、H5
、以及各种小程序等多个平台,其优势在于高贵的Vue语法与海量的轮子,可以说在诸多框架中,uni-app拥有最高的开发效率。
uni-app在国内热度较高,使用Vue.js开发所有前端应用,其优势在于生态丰富,案例较多,学习成本低,且支持热更新,开发高效,维护至今已拥有成熟的文档及社区支持。
uni-app集成了各种登录、支付、分享、地图等支持,对于国内环境而言非常友好,相比之下RN、flutter使用的是Google服务及Facebook登录,在国内都不支持。
一套代码编到13个平台,这不是梦想。眼见为实,扫描13个二维码,亲自体验最全面的跨平台效果!
这是uni-app打市场时喊出最响亮的口号,但也正因其跨平台过多,导致至今uni-app仍有很多坑未填,文档在某些方面也略显混乱,对于开发者而言,就需要去熟悉各个平台的规则。
uni-app由DCloud
公司推出,而DCloud
公司作为小程序的始祖,其开发的框架更偏向于小程序,而非App。
在性能方面,uni-app内置了双渲染引擎,webview和weex,可随意切换。
2 Flutter
Flutter是一款移动应用程序SDK,一份代码可以同时生成iOS和Android两个高性能、高保真的应用程序。
Flutter可以说是目前市面上口碑最好,最为强大的混合开发框架。在诸多跨平台框架中,Flutter有着最好的体验,性能与构建思路最接近原生App。
相对于uni-app和RN,Flutter在性能方面有着压倒性的优势。Flutter的母公司为Google
,而Google
作为一个轮子大厂,直接在两个平台上重写了各自的UIKit,对接到平台底层,减少UI层的多层转换,这使得Flutter拥有了可以比肩原生的UI性能,这一优势在滑动、拖动、播放动画效果时尤为明显。
Flutter使用Dart语言进行开发,Dart是一个静态语言,这也是相对于js的一个优势。Dart可以被编译成js,但是看起来更像java。静态语言可以避免错误,获得更多的编辑器提示词,极大的增加可维护性。
在UI表现方面,Flutter用于极为优秀的动画设计。其实现方式为在每一帧渲染正确的组件,从而形成连贯的动画。这种十分暴力的操作在Flutter上却看不到明显的卡顿,这也是Flutter的一个强大之处。相比之下其他跨平台框架几乎不能设计动画……往往会遭遇非常严重的性能问题。同时Flutter不依赖于CSS等外部解释器,几乎不存在UI表达不理想,渲染不正常的情况,可以获得非常稳定的UI表达效果。
然而在Flutter诸多优秀的表现之后,同时存在着很明显的缺陷。
作为一款跨平台框架
,使用Flutter开发却仍然难以避免需要手写相当一部分的原生代码,这对于非专业人士(Android与IOS开发人员)而言十分不友好,原因在于选择跨平台框架,很大程度是为了避免接触原生,降低学习与维护成本,而如果团队中存在专业的Android与IOS开发人员,又没有选择混合开发的必要,这就产生了非常尖锐的矛盾。
Flutter提倡“组合”,而不是“继承”。在iOS开发中,我们经常会继承UIView,重写UIView的某个生命周期函数,再添加一些方法和属性,来完成一个自定义的View。但是在Flutter中这些都是不可能的——属性都是final的,例如你继承了了一个Container,你是不能在它的生命周期中修改他的属性的。这导致了初学时很难想明白如何去构建一个完整的组件。
与此同时,Google在UI控件方面做的比较糟糕。例如Appbar组件,它的高度是写死(const)的,而Flutter又使用了“组合”的方式,无法直接对其进行修改,类似问题数不胜数,这会为开发人员带来很多困扰。
Flutter的缺点还表现在:
- 适配问题,曾出现开发工具版本升级后,旧代码不兼容问题。
- Flutter packages和Dart packages上第三方sdk繁杂,适配性差,不可乱用。
- 代码可读性很差,使人联想起十年前前端开发难以避免的回调地狱。
- Widget的类型难以选择。
- UI风格与国内有很大差异,更偏向圆圆滚滚的Material风,(大)部分用户群体很可能难以接受。
- 目前几乎没有第三方开发者平台开发Flutter能力的SDK,需要原生去集成。
- 打包后,apk/ipa要大很多。
总结一下,在跨平台框架中,Flutter效果最佳,潜力巨大,但开发语言为Dart,开发思维接近原生,导致其成本高于其他框架。
详见参考文档【浅谈flutter的优点与缺点】、【flutter框架优缺点】。
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'AutoDriver',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Login(),
);
}
}
...省略....
Widget get _appBar {
return Column(
children: <Widget>[
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Color(0x66000000), Colors.transparent],
begin: Alignment.topCenter,
end: Alignment.bottomCenter)),
child: Container(
padding: EdgeInsets.fromLTRB(0, 20, 0, 0),
height: 80.0,
decoration: BoxDecoration(
color:
Color.fromARGB((appBarAlpha * 255).toInt(), 255, 255, 255)),
child: SearchBar(
searchBarType: appBarAlpha > 0.2
? SearchBarType.homeLight
: SearchBarType.home,
inputBoxClick: _jumpToSearch,
speakClick: _jumpToSpeak,
defaultText: SEARCH_BAR_DEFAULT_TEXT,
leftButtonClick: () {},
),
),
),
Container(
height: appBarAlpha > 0.2 ? 0.5 : 0,
decoration: BoxDecoration(
boxShadow: [BoxShadow(color: Colors.black12, blurRadius: 0.5)]),
)
],
);
}
注:Flutter是Google的产品,国内禁用Google。
3 RN(React Native)
使用 React 来创建 Android 和 iOS 的原生应用
React Native是一个使用React
和应用平台的原生功能来构建Android和IOS应用的开源框架,由Facebook于2015年4月开源。它可将标记元素转化为真实的原生UI元素,同时与主UI线程分开工作以保证性能。
RN拥有仅次于Flutter的性能,运行流畅,但难以避免发热、高功耗问题;其开发语言虽然为React语言,但如果希望将其优化到理想的程度,仍然难以避免接触原生,就目前已有的案例来看,对于RN开发,最理想的方式是Android、IOS、RN三线并行,以保证动画、列表等组件能够流畅运行。
优点
- React Native可将标记元素转化为真实的原生UI元素,利用在任何平台上所呈现视图的现有方法。
- React Native与主UI线程分开工作,所以应用程序可以在不牺牲功能的前提下保持最大的性能。
- 以React为开发框架,开发效率较高。
缺点
- RN在动画效率和性能的支持还存在一些问题,且性能问题基本无解。
- RN严重依赖于
Facebook
的维护。苹果在iOS
上每次技术的更新、政策的改变都会让原来使用了RN代码库受到影响,等待Facebook
和社区的修复会妨碍 App 的更新和用户体验。
4 对比
4.1 性能
在性能表现上,webview < RN/weex < flutter(uni-app使用webview与weex)
而在开发难度方面则相反,flutter的上手难度远远高于RN与uni-app,当布局复杂的界面时,flutter的代码嵌套令人崩溃,而使用CSS的RN和uni-app则更加灵活
<div class="greybox">
<div class="redbox">
smaple text
</div>
</div>
.greybox {
display: flex;
align-items: center;
justify-content: center;
background-color: #e0e0e0; /* grey 300 */
width: 320px;
height: 240px;
font: 18px
}
.redbox {
background-color: #ef5350; /* red 400 */
padding: 16px;
color: #ffffff
}
var container = new Container( // grey box
child: new Center(
child: new Container( // red box
child: new Text(
"smaple text",
style: new TextStyle(
color: Colors.white,
fontSize: 18.0,
),
),
decoration: new BoxDecoration(
color: Colors.red[400],
),
padding: new EdgeInsets.all(16.0),
),
),
width: 320.0,
height: 240.0,
color: Colors.grey[300],
);
性能的提升是有代价的,flutter提供的布局写法是被限制过的,所以解析快、渲染快,它通过降低代码的灵活性与开发效率换取更高的性能。
4.2 开发效率
在开发效率方面,flutter是当之无愧的最差,RN紧随其后。将它们放在一起说,是因为RN和flutter都有一个很不中国化的设计:在两个平台上,使用两套UI库。
flutter在iOS上写一个button,要用CupertinoButton,是iOS风格的控件,在Android上则要用RaisedButton,是Material风格的控件。
rn也是如此,它的官方说法是:learn once,write anywhere,而不是:write once,run anywhere。因为它确实要求开发者写2套代码。
而在中国,人们普遍偏爱贴近iOS的中性风格,对Material风格的接受程度近乎于0(见微信Material临时版本的流产),所有的App都是相同的风格,所以对于国内的开发者,一套通用UI足够,两套毫无意义。
所以uni-app作为当前唯一的主流国产跨平台框架,默认使用了这种中性的iOS风格,真正的做到了write once,run anywhere。相比洋气的flutter与RN,更加符合国内环境。
总结:uni-app维护一套代码即可,RN与flutter则需要维护三套代码(iOS,Android,JS/Dart)。
4.3 动态性
混合开发往往有一个Nation不具备的优势:动态性,即远程动态载入js代码。前端开发者普遍认为动态性是天经地义的,但实际上flutter并不支持。因为它是有编译优化概念的,如果提供动态性支持,会影响它的性能。
业内有些开发者,改造了flutter,用一个独立的v8/jscore来加载动态js代码,去操作flutter布局引擎的渲染,但这一方案会造成性能明显下降,同时还大大增加了包的体积,还不如直接用RN/uni-app。
4.4 技术学习成本
flutter,要求开发者学习dart,了解dart和flutter的API、要求精通flex布局,要求原生开发协作。
RN,要求开发者学习React,要求精通flex布局,要求原生开发协作。
uni-app,要求开发者学习vue,了解小程序。
可见在技术学习成本上,flutter > RN > uni-app,而相较于其他二者,uni-app的上手成本太低了,没有任何附加专有技术。
4.5 生态对比
任何开发引擎,都离不开生态。
对于国外的开发者,RN、flutter的生态肯定比uni-app好,比如Facebook登陆分享、Google地图等。
但对于国内的开发者则相反,中国开发者需要的全端推送(UniPush集成了iOS、华为、小米、OPPO等众多原厂推送)、各种国内登陆、支付、分享SDK、各种国内地图、各种ui库、以及Echart图表等,都是在uni-app体系里,而RN与flutter所提供的部分Google/Facebook服务在国内是无法正常使用的(墙)。uni-app的插件市场有数千款插件,不能说应有尽有,但确实是最丰富的跨端开发框架生态了。
另外uni-app的生态还强在以下方面:
- App和H5提供了renderjs技术,使得浏览器专用的库也可以在App和H5里使用,比如echart、threejs等。
- 兼容微信小程序 JS SDK,丰富的小程序生态内容可直接引入uni-app,并且在App侧通用。
- 兼容微信小程序自定义组件,并且App、H5侧通用。