?

基于移動端混合(hybird)開發的通信交互方案

2022-08-31 17:29岳奎
電腦知識與技術 2022年19期
關鍵詞:通信移動互聯網

摘要:隨著移動互聯網應用大量投入市場,每天都有很多各行各業應用產品被開發出來,這就要求應用的開發效率被不斷提升。由于現有流行的原生客戶端IOS和Android開發周期較長,平臺一致性有差異,雙端開發人效高。那么可能會用到Web相關技術(HTML5、JavaScript、CSS3)作為替代原生開發的一種方案,此時會涉及原生應用和網頁之間的交互和通信,而通信原理就顯得尤為重要。原生的交互和通信一般會有比如設置頂部導航欄標題,播放聲音、拍攝照片、地理定位、聲音和傳感器等功能。該文通過分析當前原生和H5之間多種通信方式的優缺點以及目前主流的跨端方案,給出一個較為合理的混合開發通信交互方案。

關鍵詞:移動互聯網;混合開發(Hybird)通信;? schema協議;React Native

中圖分類號:TP311? ? ? 文獻標識碼:A

文章編號:1009-3044(2022)19-0040-02

最早的混合開發解決方案要追溯到Apache Cordova[1](PhoneGap)時代,當時最主要解決的問題就是讓開發者們可以在網頁中能夠調用到IOS、Android等智能手機的核心功能,例如地理定位、聯系人、拍攝照片等。那么必然就要和原生Native通信和交互,而通信和交互又是混合開發中比較重要的、比較偏基礎底層實現的一個環節。一個具有高可用性,高性能的通信過程封裝庫可以在實際的業務開發或項目實踐中很好地避免問題的發生。那么高頻通信且偏底層的方案必然就存在一定約定規范,所以一個標準的、規范化、通用的跨語言規范或者協議就尤為重要。本文就針對以上提出的問題先進行基于兩端Android和IOS基礎底層的通信方法的探索和梳理,同時給出一個較為合理的規范協議通信和交互的標準。

1 原生Android和網頁(HTML)之間的通信方式

在Android中如果希望提供Web應用或者網頁功能,通常是使用WebView[2]執行該操作。因為WebView類是Anrdoid的View類的擴展。所以通信就是Android里(Kotlin或Java)的代碼和WebView中的JavaScript代碼進行通信。那么通常會存在Android代碼調用JavaScript代碼或者JavaScript代碼調用Android代碼。

1.1 Android代碼調用JavaScript代碼

在Activity里OnCreate()方法中向應用添加WebView實例,然后使用loadUrl方法加載網頁或者通過loadData方法去加載HTML字符串。這里可以理解成webview就是瀏覽器,Android可以像瀏覽器控制臺或eval一樣執行前端的JS代碼。

1.2 JavaScript代碼調用Android代碼

常見有兩種方式,方式一是在使用WebView時,可以在JavaScript代碼和客戶端Android代碼之間創建新接口,該接口的實現就是Android代碼側調用addJavascriptInterface(),并傳入類實例以綁定到JavaScript以及JavaScript可調用以訪問類的接口名稱。然后JavaScript側就可以直接調用接口名稱下的實例方法了。方式二是通過攔截網頁的URL地址實現的通信,比如可以重載WebViewClient的shouldOverrideUrlLoading()方法,來判讀當前請求的URL是否需要做特殊處理邏輯。注意這里的URL不僅限于網頁也可以是各種靜態資源文件比如圖片、音頻等。

2 原生IOS和網頁(HTML)之間的通信方式

在IOS中承載網頁的有UIWebView[3]和WKWebView[4],UIWebView目前已廢棄,該文暫不做闡述,以下的webview均指WKWebView。WKWebView是IOS8才出現的。WKWebView和JavaScript代碼的通信過程方式和Android的WebView基本一致,這里省略過程圖。

2.1 IOS代碼調用JavaScript代碼

主要用到WKWebView的方法evaluateJavaScript[5],有三個重載方法,比較常用三個參數同時帶返回值的。具體是用到了wkwebview中的evaluateJavaScript方法。

2.2 JavaScript代碼調用IOS代碼

IOS也有兩種方式,方式之一也是攔截URL地址請求,然后做不同處理來進行通信,核心實現是基于對WKNavigationDelegate中的WKNavigationAction的實現。方式二是利用基于webkit內核的瀏覽器的JavaScriptCore去做IOS代碼和JavaScript代碼之間接口實現,因為JavaScriptCore[6]有JSVirtualMachine、JSContext和JSValue,這里主要是利用JSContext創建一個JavaScript代碼執行環境然后利用JSVirtualMachine提供的能執行JavaScript代碼的虛擬機,然后執行處理JSValue具體的值。

3 通信會遇到的問題以及解決方案思路

通過以上通信方式介紹,1.2中的方式一和2.2中的方式二顯然對于雙端(Native和HTML)都有比較強深的侵入性,不利于工程化結構。而作為瀏覽器網頁的基礎能力,對于URL的攔截和直接執行JavaScript代碼顯然簡單,高效。但實際會遇到很多問題。比如雙方通信的數據結構怎么定義,有回執的消息如何實現,cookie狀態如何同步,安全漏洞[2]等。

3.1通信數據結構如何定義

探討以URL為基礎,定義協議規則比如:schema://host/path?query其中schema定義插件名字或APP協議,客戶端僅接收內置于代碼中的schema,比如fb。這樣范圍可控。host用來區分模塊比如訂單模塊、用戶模塊等含義。path用來定義模塊里的子項比如訂單的詳情、訂單的列表。query子項攜帶的額外查詢參數,比如id。完整的結構定義例子如:fabcd://order/detail?id=1234。

3.2 Cookie如何同步狀態到HTML中

常用的是CookieManager,其作用主要有兩點,一是cookie可以實現同步到WebView或WKWebView中;二是可以請求時攜帶cookie信息。

3.3通信消息回執如何實現

核心原理是傳遞一個全局唯一的隨機數作為雙方接口的方法名字,JavaScript提前注冊該具名函數,以字符串形式傳遞到Native側,在適當的時機執行該具名函數。這種模擬全雙工通信,需要考慮消息時序[3],構建消息隊列,考慮限流、節流、冪等發送消息。

3.4頁面棧問題考慮

頁面棧會有諸多問題,比如離線時導航欄如何顯示HTML的title文本,是否可以在網絡錯誤時不顯示白屏網頁,點擊重試按鈕就可以重試下載離線HTML資源,HTML頁面間如何實現傳參,如何實現自定義是否返回等?;谝陨蠁栴},方案一是禁止HTML里的跳轉,統一走Native單獨創建WebView實例進行跳轉,優勢是標準統一都有Native去控制,HTML不用去關心返回或者關閉,缺陷是硬件開銷大。方案二是用復雜的時序來確定由H5處理返回還是NA處理返回。具體是,當用戶點擊了返回按鈕而非關閉按鈕時,NA調用JS的onBackClick。然后JS自己這邊依照業務邏輯或者自己的頁面棧是否為根來決定自己要如何處理。若需要關閉H5頁面,則調用NA close,若調用自行處理,則調用自己的history.back。并且調用NA的方法已處理的回調。若NA長時間未收到回調,則自動關閉頁面。

4 目前流行的混合通信相關方案分析

4.1 React-Native

我們先從官網給出的定義開始了解,React-Native[7]是一個使用React和應用平臺的原生功能來構建Android和IOS應用的開源框架。也就是可以使用JavaScript代碼(react代碼)訪問React Native的模塊,進而最終調用原生模塊。這個我們上邊提到的JS代碼執行NA的代碼,也就是1.2中的android利用addJavascriptInterface和ios利用JavaScriptCore來實現直接讓JS代碼調用到原生的方法會不會一樣呢,接下來就來對此分析一下。

4.1.1 Android端通信模型

首先Android的語言大多是Java,當然還有kotlin,這里先基于Java。React-Native在Native端的框架實現就是用的Java語言,那么本質上是Java和JavaScript兩種語言程序之間的調用。那么其實上述已經說到了Webview之間的通信方式,但是React-Native和Webview沒啥關系,所以這里猜測可能是利用的是so庫,因為react-native必然依賴于webkit解析,而解析完了要和Java通信必然會找到一個中間的產物,也就是更往底層走,也就是C/C++做的一個bridge。

4.1.2 IOS端的通信模型

IOS和React-Native通信其實大致與Android相同,都是依賴于C/C++編寫的Bridge,不過React-Native最新的架構是依賴于JSI,JSI核心要做的事就是對JS引擎與Native(C++)之間相互調用的封裝。下面簡單闡述下通信過程,首先js側會直接去調用已經內置好的NativeModules或者三方的NativeModules,那么就會進入一個MessageQueue隊列中,這個隊列中存放是JS調用NativeModules方法的隊列,這里是異步通信的,因為JS本身是單線程,如果同步執行,必然會阻塞后續JS執行。這里的異步執行時機也很重要,一般JS不會主動傳遞數據到OC,在調用OC方法時,會把ModuleID,MethodID等數據添加到一個隊列里,等OC過來調用JS的任意方法時,再把這個隊列返回給OC,此時OC再執行這個隊列里要調用的方法。這樣的好處就是保證了JS側和Native側的事件和邏輯同步,同時JS也可以順便做call native,就避免JS和Native之間的頻繁通信了。

5 通信整體解決方案以及架構圖

通過從最傳統的Aphche Cordova混合開發方式、自主探索混合開發通信,然后再到主流的跨端方案[4-5]探究其通信方案,探索出傳統混合開發通信[6]經典方法是Native端會對URL進行攔截,但這里的URL最好是滿足協議規范的schema規范,有host、子模塊、query、同時還有約定的消息格式加解密、cookie的管理、特定的消息時序等等,解析后處理完畢后不管處理成功還是失敗,都會執行對應回調方法通知前端JS側,而JS側會提前被注入一個對象[7],此對象包含了一些NA的方法,有需要時就調用NA的方法并傳入對應的協議scheme和與之關聯的參數,比如處理完的回調等;整體架構圖如圖1所示:

6 總結

本文重點先是闡述了早期的Android和IOS與HTML網頁之間通信的基本原理,知道基本原理再看現如今的跨端方案,?有很多實現通信方式也是基于基本的原理不斷進行演化而來,因為基本的跨語言通信方式,要么跨進程間通信,要么就通過更底層的語言(C/C++)實現中間語言傳輸通信交流。然而本身自主探索通信交互方案就會遇到一些世界要考慮的問題,比如協議制定、頁面棧管理、cookie狀態同步,消息時序等本文結合實踐經驗給出一些實踐經驗結論供參考,同時整理出理想的架構方案圖。按照此基地接入至少能保證協議可維護、可擴展。

參考文獻:

[1] 王亞飛.Apache Cordova移動應用開發實戰/跨平臺移動開發叢書[M].北京:清華大學出版社,2017.

[2] 柯芬芬.跨平臺移動應用開發技術的安全性研究[J].無線互聯科技,2020,17(5):152-153.

[3] 鄒瓊俊.H5+跨平臺移動應用實戰開發[M].北京:北京航空航天大學出版社,2019.

[4] 向治洪.React Native移動開發實戰2版[M].北京:人民郵電出版社,2020.

[5] 邱鵬源.React Native精解與實戰[M].北京:機械工業出版社,2018.

[6] 張靜,薛茹.基于JSBridge技術的跨平臺移動應用開發研究[J].信息與電腦(理論版),2021,33(6):100-102.

[7] 邵增光.一種插件化JSBridge的實現方法:CN108804082A[P].2018-11-13.

收稿日期:2021-10-11

作者簡介:岳奎(1989—),男,陜西漢中人,本科,高級前端工程師,主要研究方向為大前端。

猜你喜歡
通信移動互聯網
基于“一級調度、兩級運維”的通信管理體系研究①
微美學
對數字微波通信技術的研究
大數據環境下基于移動客戶端的傳統媒體轉型思路
基于移動互聯網的心理健康教育初探
91香蕉高清国产线观看免费-97夜夜澡人人爽人人喊a-99久久久无码国产精品9-国产亚洲日韩欧美综合