日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人工智能 > ChatGpt >内容正文

ChatGpt

Hybrid-APP技术原理

發(fā)布時間:2023/12/4 ChatGpt 69 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Hybrid-APP技术原理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

源寶導讀:Hybrid-APP技術不僅具有“Native APP的良好交互體驗”同時也具備“Web APP跨平臺開發(fā)的優(yōu)勢”。既然Hybrid-APP有這么多優(yōu)勢,那么究竟什么樣的APP才算Hybrid App呢?本文將分享我們的技術研究成果。

一、什么是Hybrid-APP

  • 狹義的Hybrid:

    • 也是現(xiàn)在大家普遍認知的,Hybrid就是一種給 WebView 增加一些js通信可以調(diào)用原生API的方式。

  • 廣義Hybrid:

    • 前端的開發(fā)思路與客戶端原生的開發(fā)思路相結(jié)合。

    • 通過原生的配合,把原本js or 前端開發(fā)做不到的事情做到了,用原生的方式增強了原本的前端技術能力。

    • WebView+Bridge、RN、weex、小程序。

? ? 我能否認為,只要是前端的開發(fā)思路與客戶端原生的開發(fā)思路相結(jié)合,就認為他是一種Hybrid?
? ? 通過原生的配合,把原本js or 前端開發(fā)做不到的事情做到了,用原生的方式增強了原本的前端技術能力,是否就是一種 Hybrid?
? ? 無論是WebView+Bridge也好,RN類似的原生渲染框架也好,小程序也好,某種意義上講,他們都算Hybrid?

Hybrid框架-基本能力

? ? 接下來我們來看一下,一個Hybrid框架所需要具備的基本能力:

  • 跨平臺能力。

? ? 這也是Hybrid應用與原生應用相比最大的優(yōu)點,一次編寫隨處運行。

  • 靈活的業(yè)務模塊擴展能力。

  • 良好的調(diào)用原生功能的能力。

? ? 由于在APP中有些功能必須由原生端提供,所以還需要有良好的調(diào)用原生功能的能力。

  • 快速更新迭代的能力。

? ? 使用原生技術開發(fā)的APP每次更新都需要上傳應用商店審核,但是使用Hybrid技術開發(fā)的應用可以繞過應用商店實現(xiàn)熱更新。

二、Hybrid-APP中通信方案

? ? 在Hybrid APP中最核心的技術就在于前端與客戶端如何通信,接下來我們看一下,js與native之間是如何通信的。

2.1、JS 調(diào)用 Native 的幾種方法

  • 假跳轉(zhuǎn)的請求攔截

  • A標簽跳轉(zhuǎn)。

  • 原地跳轉(zhuǎn)。

  • iframe跳轉(zhuǎn)。

    • 彈窗攔截

  • alert()

  • prompt()

  • confirm()

    • JS上下文注入

  • 蘋果JavaScriptCore注入。

  • 安卓addJavascriptInterface注入。

  • 蘋果scriptMessageHandler注入。

  • 2.2、Native 調(diào)用 JS 的幾種方法

    • evaluatingJavaScript 直接注入執(zhí)行JS代碼

    ? ? JS是一個腳本語言,任何一個JS引擎都可以在任意時機直接執(zhí)行JS代碼,我們可以把任何Native想要傳遞的消息/數(shù)據(jù)直接寫進JS代碼中。

    • loadUrl 瀏覽器用’javascript:’+JS代碼做跳轉(zhuǎn)地址

    ? ? 在瀏覽器中,可以直接用’javascript:xxxx’來簡單的執(zhí)行一些JS代碼,這個方法只有安卓可以用,因為iOS必須先將url字符串生成Request再交給webview去load

    • WKUserScript WKWebView的 addUserScript 方法

    ? ? WKWebView官方提供了一個Api,可以讓WebView在加載頁面的時候,自動執(zhí)行注入一些預先準備好的JS

    2.2.1、假跳轉(zhuǎn)的請求攔截

    ? ? 假跳轉(zhuǎn)的請求攔截 就是由網(wǎng)頁發(fā)出一條新的跳轉(zhuǎn)請求,跳轉(zhuǎn)的目的地是一個非法的壓根就不存在的地址。

    ? ? url地址由協(xié)議、域名、路徑、參數(shù)這么幾個部分構(gòu)成,我們可以構(gòu)建一條假的url:用協(xié)議與域名當做通信識別、用路徑當做指令識別、用參數(shù)當做數(shù)據(jù)傳遞。

    ? ? 客戶端會無差別攔截所有請求,真正的url地址應該照常放過,只有協(xié)議域名匹配的url地址才應該被客戶端攔截,攔截下來的url不會導致webview繼續(xù)跳轉(zhuǎn)錯誤地址,因此無感知,相反攔截下來的url我們可以讀取其中路徑當做指令,讀取其中參數(shù)當做數(shù)據(jù),從而根據(jù)約定調(diào)用對應的native原生代碼。

    • JS發(fā)起調(diào)用

    ? ? JS其實有很多種方式發(fā)起假請求,跟發(fā)起一個新請求沒啥兩樣,只要按協(xié)議約定 生成假請求地址,正常的發(fā)起跳轉(zhuǎn)即可,任何一種方式都可以讓客戶端攔截住。

    • 客戶端攔截

  • 安卓的攔截方式:shouldOverride UrlLoading。

  • UIWebView的攔截方式:webView: shouldStartLoadWithRequest :navigationType。

  • WKWebView的攔截方式:webView: decidePolicyForNavigationAction :decisionHandler。

  • 2.2.2、彈窗攔截

    • JS發(fā)起調(diào)用

    ? ? 可以使用alert/confirm/prompt三種彈框,每種彈框都可以由JS發(fā)出一串字符串,用于展示在彈框之上,而此字符串恰巧就是可以用來傳遞數(shù)據(jù),我們把所有要傳遞通訊的信息,都封裝進入一個js對象,然后生成字典,最后序列化成json轉(zhuǎn)成字符串。

    • 客戶端攔截

  • 安卓的攔截方式:onJsPrompt。

  • UIWebView的攔截方式:不支持截獲任何一種彈框。

  • WKWebView的攔截方式:webView: runJavaScriptText InputPanelWith Prompt :balbala。

  • 2.2.3、蘋果UIWebview JavaScriptCore注入

    • 客戶端注入

    ? ? UIWebView可以通過KVC的方法,直接拿到整個WebView當前所擁有的JS上下文documentView.webView.mainFrame.javaScriptContext。
    ? ? 拿到了JSContext,一切的使用方式就和直接操作JavaScriptCore沒啥區(qū)別了,我們可以把任何遵循JSExport協(xié)議的對象直接注入JS,讓JS能夠直接控制和操作。

    • JS調(diào)用

    ? 在沒經(jīng)過客戶端注入的時候,直接使用調(diào)用callNativeFunction()會報 callNativeFunction is not defined這個錯誤,說明此時JS上下全文全局,是沒有這個函數(shù)的,調(diào)用無效。
    ? 在執(zhí)行完客戶端注入后,此時JS上下文全局對象下面,就擁有了這個callNativeFunction的函數(shù)對象,就可以正常調(diào)用,從而傳遞數(shù)據(jù)到Native。

    2.2.4、安卓addJavascriptInterface注入

    • 客戶端注入

    ? ? 安卓的WebView有一個接口addJavascriptInterface,可以在loadUrl之前提前準備一個對象,通過這個接口注入給JS上下文,從而讓JS能夠操作,這個操作方式很類似蘋果UIWebview JavaScriptCore注入,整個機制也差別不大。

    • JS調(diào)用

    ? ? 在android端注入的對象同樣也被掛載在JS上下文全局對象下面,直接訪問即可調(diào)用。

    2.2.5、蘋果WKWebView scriptMessage Handler注入

    • 客戶端注入

    ? ? 蘋果在開放WKWebView這個性能全方位碾壓UIWebView的web組件后,也大幅更改了JS與Native交互的方式,提供了專有的交互APIscriptMessageHandler
    需要注意的是如果當前WebView沒用了,需要銷毀,需要先移除這個對象注入,否則會造成內(nèi)存泄漏,WebView和所在VC循環(huán)引用,無法銷毀。

    • JS調(diào)用

    ? ?這里不像前邊兩個注入一樣,直接注入到JS上下文全局對象里,addScriptMessageHandler方法注入的對象被放到了,全局對象下一個Webkit對象下面。
    ? ? 并且調(diào)用方式和之前的兩種方法也不同,前兩種都可以讓js任意操作所注入自定義對象的所有方法,而addScriptMessageHandler注入其實只給注入對象起了一個名字nativeObject,但這個對象的能力是不能任意指定的,只有一個函數(shù)postMessage。

    2.2.6、evaluatingJavaScript 執(zhí)行JS代碼

    ? ? 前面也簡單介紹了一下,JS是一個腳本語言,可以在無需編譯的情況下,直接輸入字符串JS代碼,直接運行執(zhí)行看結(jié)果,這也是為什么在Chrome里,在網(wǎng)頁運行的時候打開控制臺,可以輸入各種JS指令的看結(jié)果的。

    ? ? 也就是說當Native想要調(diào)用JS的時候,可以由Native把需要數(shù)據(jù)與調(diào)用的JS函數(shù),通過字符串拼接成JS代碼,交給WebView進行執(zhí)行。

    ? ? Android/iOS-UIWebView /iOS-WKWebView,都支持這種方法,這是目前最廣泛運用的方法。

    2.2.7、loadUrl 執(zhí)行JS代碼

    ? ? 安卓在4.4以前是不能用evaluatingJavaScript 這個方法的,因此之前安卓都用的是webview直接loadUrl,但是傳入的url并不是一個鏈接,而是以”javascript:”開頭的js代碼,從而達到讓webview執(zhí)行js代碼的作用。

    2.2.8、WKUserScript 執(zhí)行JS代碼

    ? ? 對于iOS的WKWebView,除了evaluatingJavaScript,還有WKUserScript這個方式可以執(zhí)行JS代碼,他們之間是有區(qū)別的,這個雖然是一種通信方式,但并不能隨時隨地進行通信。

    • evaluatingJavaScript 是在客戶端調(diào)用的時候js端會立刻執(zhí)行代碼。

    • WKUserScript 是預先準備好JS代碼,當WKWebView加載Dom的時候,執(zhí)行當條JS代碼。

    2.3、JS主動調(diào)用Native的方案對比

    三、cordova運行原理

    ? ? 在了解了Hybrid app核心的通信方案之后,我們接下來看看目前公司使用最廣泛的跨平臺技術cordova的運行原理是怎么樣的。

    3.1、客戶端入口

    ? ? 這里客戶端以Android端為例分析,Android端默認的入口是mainActivity類,我們可以看到它其實繼承CordovaActivity類,一切初始化條件是從loadUrl方法開始。

    3.2、Android端核心類CordovaActivity

    ? ? CordovaActivity內(nèi)依賴一個WebView類,一個Preferences類,一個CordovaInterface接口,并同時初始化一些配置信息。WebView具體實現(xiàn)是由CordovaWebViewImpl類,CordovaInterface接口具體實現(xiàn)是由CordovaInterfaceImpl類實現(xiàn)。

    ? ? CordovaWebViewImpl是核心類,里面會把一些插件能力初始化,用一個PluginManager進行管理,包含一個引擎類—CordovaWebViewEngine,這個引擎是通過反射的方式創(chuàng)建,自身初始化的時候把NativeToJsMessageQueue關聯(lián)起來,里面包含著以Js字符串為主的雙向鏈表,把每次從前端通過JS代碼存儲起來,然后通過綁定的橋接方式Pop出到相應的Native代碼中去。

    ? ? 最終實現(xiàn)由SystemWebViewEngine類來對Android系統(tǒng)中WebView控件進行二次包裝,這個類的初始化是在CordovaWebViewImpl類反射創(chuàng)建,相關插件和消息傳遞也是通過SystemWebViewEngine進行綁定。

    3.3、JS端cordova初始化

    ? ? Android端調(diào)用loadUrl后會啟動webview加載前端代碼,首先會加載運行cordova.js中的代碼,在cordova.js中會運行cordova/init模塊對cordova進行一個初始化,初始化中主要的核心操作就是:檢查監(jiān)聽核心事件是否觸發(fā)、平臺初始化工作、加載插件js。

    3.4、JS端平臺啟動處理

    ? ? 不同的平臺中平臺啟動處理的模塊會有一些差異,但是核心處理相差不大,在Android平臺中主要進行了三個處理:初始化通信模塊、處理物理按鍵的事件、在onCordovaReady事件被觸發(fā)時通知原生端展示webview。

    3.5、JS端插件加載處理

    ? ? 插件js加載處理中主要先會通過load方法加載cordova_plugins.js,獲取到項目中用到的插件,然后通過injectScript方法加載插件js,可以看到整個加載過程都是通過添加script標簽進行加載的,所以一旦插件數(shù)量很多對加載速度會有一定的影響。

    ? ? 這里只是加載插件的js代碼,原生端的插件加載并不是在這里進行的。

    3.6、Cordova啟動流程

    ? ? 最后來總結(jié)一下整個cordova的啟動流程,主要做了三個大的事情:

    • 原生端啟動webview加載前端代碼。

    • 初始化插件。

    • 建立通信通道。

    3.7、Cordova通信流程

    ? ? 啟動cordova后,在項目運行的過程中當前端需要調(diào)用native的能力時,就需要與native端進行通信,Cordova通信流程中主要有這么幾點:

    • Cordova通過在原生端與js端維護兩個消息隊列來處理消息回調(diào)。

    • Cordova在執(zhí)行完exec()后,android會馬上從消息隊列中取出數(shù)據(jù)同步返回,但不一定就是該次請求的數(shù)據(jù)。

    • js端通過輪詢獲取原生端消息隊列中的數(shù)據(jù)。

    四、總結(jié)

    ? ? Hybrid 的宗旨就是,如果 WebView 本身做不到,或者做起來有很大限制或者性能不佳,那么可以讓原生配合,一起做到。

    ? ? 因為Hybrid本是一個面向業(yè)務服務的東西,如果業(yè)務的野心足夠大,WebView 容器的想象空間應該是在能力上與RN/小程序看齊的,WebView 在 Hybrid 的支持下,不單純是使用Bridge 調(diào)用幾個原生 API 的事。

    ? ? 我們完全可以拆解RN中的每個環(huán)節(jié),把RN號稱比 WebView 好的原生渲染/原生組件拆解融入 WebView,我也可以學習小程序保持 WXML/WXSS的開發(fā)方式,而非RN那樣統(tǒng)一用JSX開發(fā)。

    ? ? 這種拆解不是將所有框架優(yōu)點塞在一個大而全的框架中,各種優(yōu)化方案的選擇背后一定帶來的是一些取舍。誰來決定取舍,業(yè)務決定,如果自己能深度把握這里面的設計思想,就不用在乎什么新的輪子新的框架,取其設計優(yōu)點,融入自己的業(yè)務之中即可。

    ------ END ------

    作者簡介

    李同學:?前端研發(fā)工程師,目前負責天際移動平臺的相關研發(fā)工作。

    也許您還想看

    微前端架構(gòu)在容器平臺的應用

    前端數(shù)據(jù)層落地實踐

    移動建模平臺元數(shù)據(jù)存儲架構(gòu)演進

    AI云店小程序演變之路

    基于 Go 的微服務運行情況監(jiān)控實踐

    總結(jié)

    以上是生活随笔為你收集整理的Hybrid-APP技术原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。