第一代的跨平台技术是WebView,第二代的跨平台技术是RN,第三代的跨平台技术是以Flutter为代表。
本篇将以Flutter为代表,首先说明一下为什么Flutter会成为大火的跨平台技术方案,接着我们通过拆解Flutter的跨平台技术方案,来拆解出目前主流的跨平台技术方案的发展路线。
一、Flutter为什么号称性能能媲美原生应用
二、Flutter开发的App性能还是差,差在哪里?
“一个学生考了一个会计证去和十几年老会计比算账”
如果是单纯的Flutter App,并不会有太大的性能问题。
但大部分使用Flutter的App,都是混合开发的,使用Flutter进行混合开发的App,就会存在潜在的性能问题,这是为什么呢?
渲染引擎差异。skia在iOS底层是走OpenGL渲染,iOS原生CoreAnimation底层应该是Metal渲染,效率有细微差异,skia对iOS的优化也差一些。不过现在新版本的flutter换了个跨平台的自研引擎,自称有很大优化,不过应该多少都比原生差一点点吧,毕竟为了跨平台总要有一些取舍。
dart这个语言虽然AOT下是编译到原生机器码,但仍有GC的过程,另外dart编译器好像是他们自己搞的,后端优化感觉不如LLVM。
动画渲染机制。iOS原生,Layout是在应用程序主线程,而动画是在Render进程,动画不容易被卡住;而flutter的layout和render都在渲染线程,可能会被layout卡住。
开发者差异。原生八股文卷这么多年,大家被迫对原生框架下的最佳实践&性能优化更熟悉。而flutter的开发者,相对更加能用就行。
三、Flutter逻辑层跨平台
我们先想一下,不同语言之间如果想进行通信,可以怎么做呢?
如果你没有思路,你可以想一下如果你想跟一个你不认识的人进行通信,你一般怎么做呢?
我们会找一个中间人,这个中间人既认识我,又认识我想沟通的人,这样就完成了通信。
那么在Flutter逻辑通信中也是同理,dart和java、kotlin、Objective-C、Swift之间有共同的中间人,就是C++,在Flutter中也称为Flutter引擎。
既然我们引入了一个中间人的角色,那么不可避免的就会增加通信的成本,在Flutter中,这里的成本就是 dart -> C++ -> java 的成本。
在Flutter中,C++层的通信实现主要依赖于Flutter Engine的一部分:Embedder API。Embedder API是一组C++接口,用于将Flutter引擎嵌入到不同的平台。这些接口负责处理跨语言通信、渲染、插件等任务。
具体来说,当Dart端通过Platform Channels发送消息时,消息首先会被传递到C++层的PlatformMessage对象。
然后,PlatformMessage对象会被发送到原生端(如Android或iOS)的PlatformView对象。PlatformView对象负责将消息传递给相应的原生代码(如Java、Kotlin、Objective-C或Swift),以便处理和响应。
所以基于我们上述的描述,Flutter完成了dart调用原生api的能力,那么反过来Flutter的Platform Channels机制,可以让原生调用Flutter的dart代码吗? 如果可以,是怎么调用的?
是的,Flutter的Platform Channels机制不仅可以让Dart代码调用原生代码,还可以让原生代码调用Dart代码。为了实现这种反向通信,您可以在原生代码中发送消息到Dart端,并在Dart端设置一个处理器(handler)来处理这些消息。
四、基于Flutter扩展出的跨平台方案
通过上面的分析,我们可以明确,Flutter的跨平台分案分为两个方向,第一点是UI跨平台,它使用的是基于skia进行跨平台,第二点是逻辑跨平台,Flutter引擎支持了各原生平台和dart平台的互转。
这时我们就会产生一个想法,Flutter引擎实现了dart和各个语言互通的能力,那如果我单纯把Flutter引擎对跨平台进行的能力抽出来,那是不是就可以实现各个语言之前的纯逻辑层跨平台能力了呢?
当然可以,而且现在很多跨平台组件就在向这个方向发展,通过C++为核心,实现写一份C++代码,自动生成各平台的调用接口。