介紹
最近出現的 react native 再次讓跨平臺移動端開發這個話題火起來了,曾經大家以為在手機上可以像桌面那樣通過 web 技術來實現跨平臺開發,卻大多因為性能或功能問題而放棄,不得不針對不同平臺開發多個版本。
但這并沒有阻止人們對跨平臺開發技術的探索,畢竟誰不想降低開發成本,一次編寫就處處運行呢?除了 react native,這幾年還出現過許多其它解決方案,本文我將會對這些方案進行技術分析,供感興趣的讀者參考。
為了方便討論,我將它們分為了以下 4 大流派:
web 流:也被稱為 hybrid 技術,它基于 web 相關技術來實現界面及功能 代碼轉換流:將某個語言轉成 objective-c、java 或 c#,然后使用不同平臺下的官方工具來開發 編譯流:將某個語言編譯為二進制文件,生成動態庫或打包成 apk/ipa/xap 文件 虛擬機流:通過將某個語言的虛擬機移植到不同平臺上來運行
web 流
web 流是大家都比較了解的了,比如著名的 phonegap/cordova,它將原生的接口封裝后暴露給 javascript,可以運行在系統自帶的 webview 中,也可以自己內嵌一個 chrome 內核 。
作為這幾年爭論的熱點,網上已經有很多關于它的討論了,這里我重點聊聊大家最關心的性能問題。
web 流最常被吐槽的就是性能慢(這里指內嵌 html 的性能,不考慮網絡加載時間),可為什么慢呢?常見的看法是認為「dom 很慢」,然而從瀏覽器實現角度來看,其實 dom 就是將對文檔操作的 api 暴露給了 javascript,而 javascript 的調用這些 api 后就進入內部的 c 實現了,這中間并沒有多少性能消耗,所以從理論上來說瀏覽器的 dom 肯定比 android 的「dom」快,因為 android 的展現架構大部分功能是用 java 寫的,在實現相同功能的前提下,c 不大可能比 java 慢(某些情況下 jit 編譯優化確實有可能做得更好,但那只是少數情況)。
所以從字面意思上看「dom 很慢」的說法是錯誤的,這個看法之所以很普遍,可能是因為大部分人對瀏覽器實現不了解,只知道瀏覽器有 dom,所以不管什么問題都只能抱怨它了。
那么問題在哪呢?在我看來有三方面的問題:
早期瀏覽器實現比較差,沒有進行優化 css 過于復雜,計算起來更耗時 dom 提供的接口太有限,使得難以進行優化
第一個問題是最關鍵也是最難解決的,現在說到 web 性能差主要說的是 android 下比較差,在 ios 下已經很流暢了,在 android 4 之前的 webview 甚至都沒有實現 gpu 加速,每次重繪整個頁面,有動畫的時候不卡才怪。
瀏覽器實現的優化可以等 android 4.4 慢慢普及起來,因為 4.4 以后就使用 chrome 來渲染了。
而對于最新的瀏覽器來說,渲染慢的原因就主要是第二個問題:css 過于復雜,因為從實現原理上看 chrome 和 android view 并沒有本質上的差別,但 css 太靈活功能太多了,所以計算成本很高,自然就更慢了。
那是不是可以通過簡化 css 來解決?實際上還真有人這么嘗試了,比如 famo.us,它最大的特色就是不讓你寫 css,只能使用固定的幾種布局方法,完全靠 javascript 來寫界面,所以它能有效避免寫出低效的 css,從而提升性能。
而對于復雜的界面及手機下常見的超長的 listview 來說,第三個問題會更突出,因為 dom 是一個很上層的 api,使得 javascript 無法做到像 native 那樣細粒度的控制內存及線程,所以難以進行優化,則在硬件較差的機器上會比較明顯。對于這個問題,我們一年前曾經嘗試過嵌入原生組件的方式來解決,不過這個方案需要依賴應用端的支持,或許以后瀏覽器會自帶幾個優化后的 web components 組件,使用這些組件就能很好解決性能問題。
現階段這三個問題都不好解決,所以有人想干脆不用 html/css,自己來畫界面,比如 react canvas 直接畫在 canvas 上,但在我看來這只是現階段解決部分問題的方法,在后面的章節我會詳細介紹自己畫 ui 的各種問題,這里說個歷史吧,6 年前瀏覽器還比較慢的時候,bespin 就這么干過,后來這個項目被使用 dom 的 ace 取代了,目前包括 textmirror 和 atom 在內的主流編輯器都是直接使用 dom,甚至 w3c 有人專門寫了篇文章吐槽用 canvas 做編輯器的種種缺點,所以使用 canvas 要謹慎。
另外除了 canvas,還有人以為 webgl 快,就嘗試繪制到 webgl 上,比如 html-gl,但它目前的實現太偷懶了,簡單來說就是先用 html2canvas 將 dom 節點渲染成圖片,然后將這個圖片作為貼圖放在 webgl 中,這等于將瀏覽器中用 c 寫的東東在 javascript 里實現了一遍,渲染速度肯定反而更慢,但倒是能用 glsl 做特效來忽悠人。
硬件加速不等同于「快」,如果你以為硬件加速一定比軟件快,那你該抽空學學計算機體系結構了
其實除了性能問題,我認為在 web 流更嚴重的問題是功能缺失,比如 ios 8 就新增 4000 api,而 web 標準需要漫長的編寫和評審過程,根本趕不上,即便是 cordova 這樣自己封裝也忙不過來,所以為了更好地使用系統新功能,寫 native 代碼是必須的。
代碼轉換流
前面提到寫 native 代碼是必須的,但不同平臺下的官方語言不一樣,這會導致同樣的邏輯要寫兩次以上,于是就有人想到了通過代碼轉換的方式來減少工作量,比如將 java 轉成 objective-c。
這種方式雖然聽起來不是很靠譜,但它卻是成本和風險都最小的,因為代碼轉換后就可以用官方提供的各種工具了,和普通開發區別不大,因此不用擔心遇到各種詭異的問題,不過需要注意生成的代碼是否可讀,不可讀的方案就別考慮了。
接下來看看目前存在的幾種代碼轉換方式。
將 java 轉成 objective-c
j2objc 能將 java 代碼轉成 objective-c,據說 google 內部就是使用它來降低跨平臺開發成本的,比如 google inbox 項目就號稱通過它共用了 70% %u7684代碼,效果很顯著。
可能有人會覺得奇怪,為何 google 要專門開發一個幫助大家寫 objective-c 的工具?還有媒體說 google 做了件好事,其實吧,我覺得 google 這算盤打得不錯,因為基本上重要的應用都會同時開發 android 和 ios 版本,有了這個工具就意味著,你可以先開發 android 版本,然后再開發 ios 版本。。。
既然都有成功案例了,這個方案確實值得嘗試,而且關鍵是會 java 的人多啊,可以通過它來快速移植代碼到 objective-c 中。
將 objective-c 轉成 java
除了有 java 轉成 objective-c,還有 objective-c 轉成 java 的方案,那就是 myappconverter,比起前面的 j2objc,這個工具更有野心,它還打算將 ui 部分也包含進來,從它已轉換的列表中可以看到還有 uikit、coregraphics 等組件,使得有些應用可以不改代碼就能轉成功,不過這點我并不看好,對于大部分應用來說并不現實。
由于目前是收費項目,我沒有嘗試過,對技術細節也不了解,所以這里不做評價。
將 java 轉成 c#
mono 提供了一個將 java 代碼轉成 c# 的工具 sharpen,不過似乎用的人不多,star 才 118,所以看起來不靠譜。
還有 juniversal 這個工具可以將 java 轉成 c#,但目前它并沒有發布公開版本,所以具體情況還待了解,它的一個特色是自帶了簡單的跨平臺庫,里面包括文件處理、json、http、oauth 組件,可以基于它來開發可復用的業務邏輯。
比起轉成 objective-c 和 java 的工具,轉成 c# 的這兩個工具看起來都非常不成熟,估計是用 windows phone 的人少。
將 haxe 轉成其它語言
說到源碼轉換就不得不提 haxe 這個奇特的語言,它沒有自己的虛擬機或可執行文件編譯器,所以只能通過轉成其它語言來運行,目前支持轉成 neko(字節碼)、javascript、actionscript 3、php、c 、java、c# 和 python,盡管有人實現了轉成 swift 的支持,但還是非官方的,所以要想支持 ios 開發目前只能通過 adobe air 來運行。
在游戲開發方面做得不錯,有個跨平臺的游戲引擎 openfl 的,最終可以使用 html5 canvas、opengl 或 flash 來進行繪制,openfl 的開發體驗做得相當不錯,同一行代碼不需要修改就能編譯出不同平臺下的可執行文件,因為是通過轉成 c 方式進行編譯的,所以在性能和反編譯方面都有優勢,可惜目前似乎并不夠穩定,不然可以成為 cocos2d-x 的有利競品。
在 openfl 基礎上還有個跨平臺的 ui 組件 haxeui,但界面風格我覺得特別丑,也就只能在游戲中用
備案涉及前置審批-備案平臺什么是掛機寶?掛機寶能做什么?我是需要注銷備案重新再備案白帽SEO和黑帽SEO有哪些本質區別云服務器怎么沒有windowsaaa云服務器推薦碼阿里云服務器怎么沒有目錄遠程打不開服務器-其他問題