• home > webfront > engineer > Architecture >

    客户端软件GUI开发技术漫谈:原生与跨平台解决方案分析

    Author:zhoulujun Date:

    各个平台的GUI开发有:GUI Winform WPF UWP Swing JavaFx Air 等,但是不能夸平台,Electron Cordova Xamarin QT C++等,给我们提供跨平台的多端技术解决方案有哪些优势,他们的工作原理是什么呢? Flutter

    原生开发应用开发

    Microsoft阵营的

    Winform

    WinForm是·Net开发平台中对Windows Form的一种称谓。

    如果你想深入的美化UI,需要耗费很大的力气,对于目前主流的CSS样式表来讲,美化Winform的界面以及自定义控件是需要耗费更多的时间的。

    WPF

    基于XML+C#+CSS的呈现方式让它在UI上有了更加灵活的设计宽度。具体看官方:https://github.com/dotnet/wpf

    WPF技术架构

    WPF和WinForms是两种完全不一样的UI技术,WPF也并不能完全取代WinForms。

    WPF不能运行在其他操作系统,并且在XAML中编写样式表,通用性还是不如HTML强,从学习应用的范围来讲,还是HTML更好一些。

    UWP

    微软为了针对移动端市场开放的开发框架,如果你的APP只需要运行在Windows下,我认为WPF或者UWP是最好的选择,毕竟在调用系统原生API上微软的亲儿子们有着巨大的优势。


    windows上各种各样的技术开发的IDE和其他程序

    • 性能上:Java最差 -> Electron -> WindowsForms -> 原生 -> WPF

    • 占内存:Java最多 -> Electron -> WPF -> WindowsForms -> 原生


    Java阵营

    Swing

    零几年学Java的老头子们几乎都是从Swing开始学起的,Swing谜一般的默认UI审美观让我直接放弃了继续学习下去的动力。

    JavaFx

    优点在于可以跨平台,缺点在于整个生态环境非常不好,与Winforms一样,自定义一些控件相对比较困难。

    Adobe阵营

    Air

    Flex程序,它的优点在于可以跨平台,可以基于Flash做出很多超级炫酷的动画特效,但是缺点主要就是效率实在是太低下了,并且在调用操作系统原生API的时候也非常不方便。随着Flash在浏览器上的节节败退,Air也悄无声息的消失在了大众的视野当中。

    Apple

    Objective-C(或现在的Swift),跟Winforms一样,可以非常方便的调用操作系统底层API,劣势也一样,不跨平台、自定义控件比较复杂,可用资源太少。现在大多数程序员都是基于C#、Java进行开发,如果不是Apple死忠,根部不会花大力气研究

    跨平台软件应用开发

    直接元素开发肯定是最好的——这样的性能肯定最有保证,但是跨平台的主要优势在于代码逻辑的复用,减少各平台同一逻辑,因人而异的开发成本。对于企业而言,一套业务逻辑可以在多处使用是最理想也是最保险的。

    Electron

    Electron是由Github开发,用HTML,CSS和JavaScript来构建跨平台桌面应用程序的一个开源库。 Electron通过将Chromium和Node.js合并到同一个运行时环境中,并将其打包为Mac,Windows和Linux系统下的应用来实现这一目的。通过Node它提供了通常浏览器所不能提供的能力。 

    electron的特点就是可以复用前端的各种轮子。所以它开发快,招人方便。还有.net :https://github.com/ElectronNET/Electron.NET

    可以方便的通过Node.JS调用系统API、可以使用SQLite做本地字典项的缓存处理,可以将复杂的计算逻辑放在客户端进行,从而减轻服务器端的压力等等。

    electron都成千上万个成熟项目在桌面里用了,什么flutter,javafx,swiftui,目前还是无法比

    electron和node-webkit(现在叫nw.js)的区别:

    。从概念上,Electron与nw.js很相似,但是他们有很重要的区别:一个主要的不同点是Electron 通过 Googles Chromium Content Module 来使用 Chromium 的功能,nw.js 则直接使用了 Chromium本身。

    electron建立在 Chromium 和 NodeJS 之上的,一个负责界面,一个负责背后的逻辑

    Electron的运行原理


    Cordova,PhoneGap

    Cordova[ˈkɔːdəbə]是 hybride 类框架,基于HTML,CSS和JavaScript的,创建移动跨平台移动应用程序的快速开发平台

    2011年10月4日Adobe公司收购了PhoneGap和PhoneGap Build的新创公司Nitobi Software,随后将Phonegap的核心代码剥离并捐给了Apache公司,并改名为了Cordova。

    核心的东西就是H5与Native的交互原理、Bridge、定义的解析规则(Engine)

     Cordova架构设计


    Cordova Application是Cordova框架独立于不同手机操作系统的一个封装层。具体包括 

    • Web App层是开发人员编写代码的主要地方,应用程序以网页的形式呈现,在一个index.html的本地页面文件中引用所需要的各种Web资源,如CSS、JavaScript、图像、影音文件等。应用程序的配置保存在config.xml文件中。

      对于使用cordova cli初始化的web app 在主目录下会存在一个config.xml,其中包含了整个app的一些基本信息:比如appName、app入口文件、白名单、webview初始化的一些配置、plugin信息、图标资源信息

    • WebView层用来呈现用户界面,即web页面的展现。例如,在Android平台是通过WebView控件实现web页面的呈现。

    • Plugins主要用于在JavaScript代码中调用各平台native的功能。Cordova项目已经包含一些核心的plugin,如电池、摄像头、通讯录等。开发人员也可以开发自定义的plugin,来实现所需要的功能。 

    Mobile OS就是具体的手机操作系统层

    Cordova预先帮我们预先封装了各种mobile os上最常用的本地api调用,然后以统一的JavaScript api形式提供给webapp开发者调用。

    对于webapp的开发者来说,无需关注系统底层调用实现细节,也就实现了所谓的“跨平台”。实际上,各平台涉及到本地能力的调用,以插件形式被封装了。(每个插件的实现实际上还是Native模式)。

    JS和Native是如何实现互调的,这里先研究安卓的

    Cordova-Android是通过addJavascriptInterface(Android Webview的API)和JS Prompt这两种方式来实现JS对于Native API的调用。

    我们先来看一个Cordova-Android框架中的一个关键类: CordovaActivity.java。

    该类继承了Android Activty类,实际上是Cordova-Android的Launcher Activity,也就是启动入口activity。

    应用启动后,核心干了两件事:读取config.xml和loadUrl。这个loadUrl实际上就是加载webapp的启动页(默认是index.html)。

    IOS具体参看《Cordova 工作原理(IOS篇)》,这里关于原理这是简介。


    React-Native

     React-Native厉害在于它能打通JS和Native Code, 让JS能够调用丰富的原生接口,充分发挥硬件的能力, 实现非常复杂的效果,同时能保证效率和跨平台性。

    在一定程度上,React Native和NodeJS有异曲同工之妙。它们都是通过扩展JavaScript Engine, 使它具备强大的本地资源和原生接口调用能力,然后结合JavaScript丰富的库和社区和及其稳定的跨平台能力,把javascript的魔力在浏览器之外的地方充分发挥出来

    React Native 架构

    React Native 渲染 在 React 框架中,JSX 源码通过 React 框架最终渲染到了浏览器的真实 DOM 中

    React 可以渲染到多平台上

    在 React Native 框架中,JSX 源码通过 React Native 框架编译后,通过对应平台的 Bridge 实现了与原生框架的通信。如果我们在程序中调用了 React Native 提供的 API,那么 React Native 框架就通过 Bridge 调用原生框架中的方法。 因为 React Native 的底层为 React 框架,所以如果是 UI 层的变更,那么就映射为虚拟 DOM 后进行 diff 算法,diff 算法计算出变动后的 JSON 映射文件,最终由 Native 层将此 JSON 文件映射渲染到原生 App 的页面元素上,最终实现了在项目中只需要控制 state 以及 props 的变更来引起 iOS 与 Android 平台的 UI 变更。 编写的 React Native代码最终会打包生成一个 main.bundle.js 文件供 App 加载,此文件可以在 App 设备本地,也可以存放于服务器上供 App 下载更新

    大多数组件都类似HTML,例如View组件跟div标签就很类似,Text组件类似于p标签。

    React Native 框架构成A diagram showing React Native's Core Components are a subset of React Components that ship with React Native.

    具体参看《ReactJS到React-Native 零碎笔记 》

    Xamarin

    Xamarin ['zæmərɪn]是一个开放源代码平台,用于通过 .NET 构建适用于 iOS、Android 和 Windows 的新式高性能应用程序。

    Xamarin主要有这么几项技术,Xamarin.Android、Xamarin.iOS和Xamarin.Forms,此外还有Xamarin.UWP、Xamarin.Windows、Xamarin.WinPhone等。本质都是对原生API做了一层C#的封装,因此在使用上与原生API会十分相似。这种封装会结合一些C#的语法特性,让开发者可以享受C#的语法糖。Xamarin.iOS是直接编译成ARM的二进制代码,因此执行效率肯定是非常高的。

    Xamarin.Android被编译成中间语言,Xamarin在APK安装包中会包含一个mono(跨平台的.NET运行环境),代码是在mono运行时和安卓本地的运行时上完成工作的。

    Mono [ˈmɒnəʊ] 虚拟机包含一个实时编译引擎,该引擎可用于如下处理器:x86,SPARC,PowerPC,ARM,S390(32位模式和64位模式),x86-64,IA64 和64位模式的 SPARC。该虚拟机可以将代码实时编译或者预先编译到原生代码。对于那些没有列出来的系统,则使用的是代码解释器。

    Xamarin 是一个抽象层,可管理共享代码与基础平台代码的通信。 Xamarin 在提供便利(如内存分配和垃圾回收)的托管环境中运行。

    Xamarin始创于2011年,旨在使移动开发变得难以置信地迅捷和简单。

    Xamarin 适用于具有以下目标的开发人员:

    • 跨平台共享代码、测试和业务逻辑。

    • 使用 Visual Studio 在 C# 中编写跨平台应用程序。

     Xamarin 允许在每个平台上创建本机 UI,并在 C# 中编写跨平台共享的业务逻辑。 在大多数情况下,80% 的应用程序代码可使用 Xamarin 进行共享。

    Xamarin最为关键的技术Xamarin.Forms,把IOS、android、UWP等平台的GUI进行了一统地抽象,开发者只需要写一套代码,编译器会在编译时将界面映射到原先控件上,从而获得原生平台的外观和性能。

    Xamarin 体系结构示意图

    Xamarin 在 .NET 的基础之上进行构建,它自动处理诸如内存分配、垃圾回收以及与基础平台的互操作性等任务。

    Xamarin之前是收费的,而且据说收费不菲,所以使用的人数比较少,在国内几乎无人问津。后来Xamarin被微软收购,现已免费开放,但是从白学.net开始,就对微软的东西不感冒了。微软的东西虽好,但是叫好不叫座。

    Flutter

    flutter 其实就是一套谷歌开源的跨平台 UI 开发框架,支持 Android 和 iOS ,并且目前开始支持 Web 和 MacOS,未来还会继续支持 Win和 Linux 平台的一套 UI 框架。

    Dart UI是一个 C++实现的 dart:ui库的 Native Binding,并且 UI Lib也是 Dart GUI程序的应用主要入口。

    Dart UI向上层提供了 window、text、canvas、geometry等通用的绘图能力, Runtime在调用 Dart UI时,Dart UI根据传递的 main entrypoint 来执行并且向 window渲染图像。

    react-native 、weex 和 flutter 都只是 UI 框架,它解决的其实是跨平台上的 UI 实现,让界面布局或者实现的业务逻辑可以在多端统一。但是它也仅仅只是 UI 框架,比如 react-native 本身就是依赖于原生控件,而 flutter 的 webview 、mapview 也都需要依赖原生开发来支撑。

    Flutter的原理 Flutter是如何设计

    GUI渲染原理,推荐阅读《03-大前端底层原理|跨平台开发方案-Flutter的渲染原理

    Dart这门语言最初就是一帮Java程序员为了方便写UI搞出来的。如果你们团队Java/Swift程序员比较多,那Flutter从上手方面来说更快。

    为什么选择Dart

    • Dart 的性能更好。Dart在 JIT模式下,速度与 JavaScript基本持平。但是 Dart支持 AOT,当以 AOT模式运行时,JavaScript便远远追不上了。

    • Native Binding。在 Android上,v8的 Native Binding可以很好地实现,但是 iOS上的 JavaScriptCore不可以,所以如果使用 JavaScript,Flutter 基础框架的代码模式就很难统一了。而 Dart的 Native Binding可以很好地通过 Dart Lib实现。

    • Fuchsia [ˈfjuːʃə] OS内置的应用浏览器就是使用 Dart语言作为 App的开发语言。而且实际上,Flutter是 Fuchisa OS的应用框架概念上的一个子集。

    • Dart是类型安全的语言,拥有完善的包管理和诸多特性。Google召集了如此多个编程语言界的设计专家开发出这样一门语言,旨在取代 JavaScript,所以 Fuchsia OS内置了 Dart。Dart可以作为 embedded lib嵌入应用,而不用只能随着系统升级才能获得更新,这也是优势之一。

    Skia是什么?

    Skia是一个 2D的绘图引擎库,其前身是一个向量绘图软件,Chrome和 Android均采用 Skia作为绘图引擎。Skia提供了非常友好的 API,并且在图形转换、文字渲染、位图渲染方面都提供了友好、高效的表现。Skia是跨平台的,所以可以被嵌入到 Flutter的 iOS SDK中,而不用去研究 iOS闭源的 Core Graphics / Core Animation。因为Android自带了 Skia,所以 Flutter Android SDK要比 iOS SDK小很多。

    QT C++

    QT最大的优势就是跨平台!高效率!但是与Objective-C一样,CPP如同一座小山横在了众多server side程序员的面前,如果没有CPP这道小山横贯在前,我认为QT是最好的Desktop Application特别是嵌入式终端的UI开发框架。

    QT另外有一个优势在于,它在UI上似乎要比之前几位要方便一些,在它的QML中甚至可以直接使用JavaScript(当然,Java也内置了JS引擎),同时QT中也包含了大量的标准CSS样式表可以使用

    如果希望自己从事真正意义上的Desktop Application development,QT绝对值得你去学习。

    QT有可视化编辑器,但是相比较而言,可能略强于NetBeans的Swing,但是跟VS比起来还是差太远了,不过大多是实际开发都是基于代码的

    x-platform

    这玩意,个人觉得没有啥奔头。

    Avalonia

    知乎有道友留言,提到Avalonia,个人之前确实没有听说过。看官方资料:https://github.com/AvaloniaUI/Avalonia,Examples of UIs built with Avalonia,确实蛮漂亮的。

    Avalonia是一个基于WPFXAML的跨平台UI框架,并支持多种操作系统:Windows(.NETFramework,.NETCore),Linux(GTK),MacOS,Android和iOS。

    不过个人对微软的 .net 都是过敏状态。2014 微软向Open SDK 投怀送抱后,微软向Java 环境贡献越来越多。微软现在越来越开放。

    NET 5 是 .NET Core 的下一步。该项目旨在通过以下几个关键方式改进 .NET:

    • 制造一个可在任何地方使用的 .NET 运行时和框架,并具有统一的运行时行为和开发人员体验。

    • 通过充分利用 .NET Core、.NET Framework、Xamarin 和 Mono 来扩展 .NET 的功能。

    • 从单个代码库构建该产品,开发人员( Microsoft 和社区)可以一起工作并一起扩展,从而改进所有方案。

    目前没有选择.net 技术栈的打算。过几年拼不动了,在去学下.net,去个压力小点的公司,或许是比送外卖好的结局把


    参考文章:

    快速了解Electron:新一代基于Web的跨平台桌面技术 https://www.cnblogs.com/imstudy/p/11022315.html

    Flutter原理简解 https://zhuanlan.zhihu.com/p/36861174

    https://zhuanlan.zhihu.com/p/65010663



    转载本站文章《客户端软件GUI开发技术漫谈:原生与跨平台解决方案分析》,
    请注明出处:https://www.zhoulujun.cn/html/webfront/engineer/Architecture/8468.html

    延伸阅读: