1. 程式人生 > >Hybrid APP之Native和H5頁面互動原理

Hybrid APP之Native和H5頁面互動原理

http://www.cnblogs.com/liubei/p/Hybrid.html

前言

參考來源

前人栽樹,後臺乘涼,本文參考了以下來源

前置技術要求

閱讀本文前,建議先閱讀以下文章

楔子

Hybrid APP的關鍵是原生頁面與H5頁面直接的互動,本文做簡單介紹

Android、iOS原生和H5的基本通訊機制

在Hybrid APP中,原生與H5的互動方式在Android和iOS上的實現是有異同的,原因是Android、iOS的通訊機制有所區別,下面介紹原生和H5相互呼叫的方法

Android端

Native調JS

4.4版本之前

// mWebView = new WebView(this); //即當前webview物件			
mWebView.loadUrl("javascript: 方法名('引數,需要轉為字串')"); 

//ui執行緒中執行
 runOnUiThread(new Runnable() {  
        @Override  
        public void run() {  
            mWebView.loadUrl("javascript: 方法名('引數,需要轉為字串')");  
            Toast.makeText(Activity名.this, "呼叫方法...", Toast.LENGTH_SHORT).show();  
        }  
});  
			

4.4以後(包括4.4)

//非同步執行JS程式碼,並獲取返回值	
mWebView.evaluateJavascript("javascript: 方法名('引數,需要轉為字串')", new ValueCallback() {
        @Override
        public void onReceiveValue(String value) {
    		//這裡的value即為對應JS方法的返回值
        }
});
			

如上所示,Native用H5頁面中的JS方法,有如下特點

  • 4.4之前Native通過loadUrl來呼叫JS方法,只能讓某個JS方法執行,但是無法獲取該方法的返回值
  • 4.4之後,通過evaluateJavascript非同步呼叫JS方法,並且能在onReceiveValue中拿到返回值
  • 不適合傳輸大量資料(大量資料建議用介面方式獲取)
  • mWebView.loadUrl("javascript: 方法名('引數,需要轉為字串')");函式需在UI執行緒執行,因為mWebView為UI控制元件(但是有一個壞處是會阻塞UI執行緒)

JS調Native

 WebSettings webSettings = mWebView.getSettings();  
 //Android容器允許JS指令碼,必須要
webSettings.setJavaScriptEnabled(true);
//Android容器設定僑連物件
mWebView.addJavascriptInterface(getJSBridge(), "JSBridge");
			

Android中JSBridge的程式碼

//Android4.2版本以上,本地方法要加上註解@JavascriptInterface,否則會找不到方法。
private Object getJSBridge(){  
    Object insertObj = new Object(){  
    	@JavascriptInterface
        public String foo(){  
            return "foo";  
        }  
        
        @JavascriptInterface
        public String foo2(final String param){  
            return "foo2:" + param;  
        }  
          
    };  
    return insertObj;  
}  
			

Html中JS呼叫原生的程式碼

//呼叫方法一
window.JSBridge.foo(); //返回:'foo'
//呼叫方法二
window.JSBridge.foo2('test');//返回:'foo2:test'
			

如上所示,Native中通過addJavascriptInterface新增暴露出來的JS橋物件,然後再該物件內部宣告對應的API方法,有如下特點:

  • 在Android4.2以上(api17後),暴露的api要加上註解@JavascriptInterface,否則會找不到方法。
  • 在api17以前,addJavascriptInterface有風險,hacker可以通過反編譯獲取Native註冊的Js物件,然後在頁面通過反射Java的內建 靜態類,獲取一些敏感的資訊和破壞

    所以,也就是為什麼Android中也會使用JSBridge來進行互動,而不是addJavascriptInterface直接暴露api

  • JS能呼叫到已經暴露的api,並且能得到相應返回值

iOS端

Native調JS

//可以取得JS函式執行的返回值
//方法必須是Html頁面繫結在最頂層的window上物件的
//如window.top.foo
//Swift
webview.stringByEvaluatingJavaScriptFromString("方法名(引數)")
//OC
[webView stringByEvaluatingJavaScriptFromString:@"方法名(引數);"];
			

如上所示,Native通過stringByEvaluatingJavaScriptFromString呼叫Html繫結在window上的函式,有如下特點

  • Native呼叫JS方法時,能拿到JS方法的返回值
  • 不適合傳輸大量資料(大量資料建議用介面方式獲取)

JS調Native

引入官方的庫檔案

#import <JavaScriptCore/JavaScriptCore.h>

Native註冊api函式(OC)

//webview載入完畢後設置一些js介面
-(void)webViewDidFinishLoad:(UIWebView *)webView{
    [self hideProgress];
    [self setJSInterface];
}

-(void)setJSInterface{
    
    JSContext *context =[_wv valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    
    // 註冊名為foo的api方法
    context[@"foo"] = ^() {
    	
    	//獲取引數
        NSArray *args = [JSContext currentArguments];
        NSString *title = [NSString stringWithFormat:@"%@",[args objectAtIndex:0]];
        //做一些自己的邏輯
        //返回一個值  'foo:'+title
        return [NSString stringWithFormat:@"foo:%@", title];
    };
    

    
}				
			

Html中JS呼叫原生的程式碼

//呼叫方法,用top是確保呼叫到最頂級,因為iframe要用top才能拿到頂級
window.top.foo('test'); //返回:'foo:test'
			

如上所示,Native中通過引入官方提供的JavaScriptCore庫(iOS7中出現的),然後可以將api繫結到JSContext上(然後Html中JS預設通過window.top.***可呼叫)。有如下特點

  • iOS7才出現這種方式,在這之前,js無法直接呼叫Native,只能通過JSBridge方式簡介呼叫
  • JS能呼叫到已經暴露的api,並且能得到相應返回值
  • iOS原生本身是無法被JS呼叫的,但是通過引入官方提供的第三方"JavaScriptCore",即可開放api給JS呼叫

原生和H5的另一種通訊方式:JSBridge

實際上,Native與H5通訊,除了前面提到的用基本方法外,還有一種廣為流行的方法:JSBridge

什麼是JSBridge

JSBridge是廣為流行的Hybrid開發中JS和Native一種通訊方式,各大公司的應用中都有用到這種方法

簡單的說,JSBridge就是定義Native和JS的通訊,Native只通過一個固定的橋物件呼叫JS,JS也只通過固定的橋物件呼叫Native,基本原理是:

H5->通過某種方式觸發一個url->Native捕獲到url,進行分析->原生做處理->Native呼叫H5的JSBridge物件傳遞迴調。如下圖

上圖簡單的介紹了下JSBridge的核心原理,具體詳細實現請參考後面詳解。

為什麼要用JSBridge

在上文中我們有提到Native和原生之間的基本通訊,既然Native和原生已經能夠實現通訊了,那為什麼還要這種通過url scheme的JSBridge方式呢,原因大致如下

  • Android4.2以下,addJavascriptInterface方式有安全漏掉
  • iOS7以下,JS無法呼叫Native
  • url scheme互動方式是一套現有的成熟方案,可以完美相容各種版本,不存在上述問題

另外,請注意,可以理解為JSBridge是一種互動理念,而上述的url scheme則是其中的一種實現,所以也就是說,就算後面實現變為了addJavascriptInterface,JavaScriptCore,也一樣是JSBridge互動

JSBridge互動的一個很大特點就是便於拓展,而且沒有重大的安全性問題,所以也就是為什麼它廣為流行

JSBridge原理以及實現

相關推薦

Hybrid APPNativeH5頁面互動原理

http://www.cnblogs.com/liubei/p/Hybrid.html 前言 參考來源 前人栽樹,後臺乘涼,本文參考了以下來源 前置技術要求 閱讀本文前,建議先閱讀以下文章 楔子 Hybrid APP的關鍵是原生頁面與H5頁面直接的互動,本文做簡單介紹

Hybrid APPNativeH5頁面交互

ren bject scrip html中 控件 his 允許 load 互相調用 Hybrid APP之Native和H5頁面交互原理 Hybrid APP的關鍵是原生頁面與H5頁面直接的交互,如下圖,痛過JSBridge,H5頁面可以調用Native的api,Nati

Hybrid APP 混合開發模式的選擇路(五:原生H5互動原理

原文出處:http://www.cnblogs.com/dailc/p/5931322.html 在Hybrid APP中,原生與H5的互動方式在Android和iOS上的實現是有異同的,原因是Android、iOS的通訊機制有所區別,下面介紹原生和H5相互呼叫的方法

appH5頁面互動

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html

androidh5頁面互動

專案h5頁面那邊需要調native頁面的充值和提現頁面 設定支援js mWebView = view.findViewById(R.id.mall_view); settings = mWebView.getSettings();

安卓 native H5互動

源生程式碼和H5的互動 android: 1: 預設的事情: android 通過內建的UI控制元件WebView來載入網頁。          網頁是用一個網路地址來表示的:          其整個使用方法很簡單如下:(android不關心實際的html5程式碼)

Nativehtml5的互動(一)h5傳資料or觸發一個Android的事件

實習的時候給了一個native 與htmlt5的互動的任務 那Android平臺來舉例 Activity.java裡面 WebView mWebView; @SuppressLint({ "JavascriptInterface", "SetJavaScriptEnab

react native原生RN的互動

前言:前端時間隨著自己的學習和研究,也寫了幾篇關於react native的文章,雖然都是比較簡的,但是都是根據自己的效果來做的流程,所以還是比較實用的,可以避免很多的坑。這篇react native

什麼是Web AppHybrid AppNative App以及區別,當前主流移動應用程式型別

隨著H5標準的釋出以及推廣,使得移動應用的開發也受到了很大影響,出於效率、成本等等的原因,移動應用的開發不在完全依賴於“原生”。 今天就簡單總結一下目前的三大主流移動應用開發型別。 APP,一般認為是 mobile application,也就是移動移動應用

App混合開發WebView進行H5頁面基本操作

現在淘寶、京東、聚划算、甚至於一些銀行的App都是利用原生加H5混合開發技術進行開發的,混合開發越來越成為App開發主流技術。WebView是android內嵌的Web頁面訪問元件,通過它可以輕鬆實

JNI Javac/c++互動,提升Java變成效率

JNI 主要是java和c++相互呼叫,java可以把效率低,耗時操作比較嚴重的邏輯放在c++裡面。可以大大提升效率和節省資源。 下面是java呼叫的windows下的 c++的dll動態庫,還有一種是標準c的linux的so動態庫。工程結構圖如下: 第一步:編寫Java程式

探索Linux 終端模擬器偽終端互動原理

寫在前面:本人水平有限,很多地方都是自己的理解,如有誤導,歡迎指正 # 終端模擬器指的是在linux桌面環境下執行的模擬終端(如下圖) # 終端模擬器為啥叫模擬器呢? 因為真正的終端是全屏顯示的黑乎乎的不帶視窗的那種,這裡帶了視窗,是基於linux的X視窗系統上模擬出來的終端裝置,

原生頁面H5頁面

“原生應用”佔統治地位   當我們為移動裝置開發應用程式時,程式設計師通常都會選擇開發“原生應用”,“原生應用”是一種使用者必須通過手機應用商店購買下載並安裝在手機儲存器內的應用程式。“原生應用”現已成為新增手機功能的首選業界標準。   因此,大多數的程式設計師都認為跟瀏覽器應用相比

前端:微信支付支付寶支付在pc端h5頁面中的應用

1:h5微信支付 使用的是https://pay.weixin.qq.com/wiki/doc/api/index.html  中的 (1):公司需要首先要配置公眾號微信支付地址和測試白名單(支付的時候顯示這個支付頁面沒許可權有可能是這個原因) 如上圖http://ww

Web AppHybrid AppNative App之間的差異

APP,一般認為是 mobile application,也就是移動移動應用程式。 目前主流應用程式大體分為三類:Web App、Hybrid App、 Native App。 1.Web App Web App 指採用Html5語言寫出的App,不需要下載安裝。類

H5頁面互動設計的缺點與解決方案

來源:世界工廠網線上生態學院 作者:布布_桃子 為什麼說H5現在越來越火,主要是因為H5以其較高的趣味性和良好的互動性受到越來越多使用者的青睞。隨著H5技術的發展,H5的型別和形式也越來越多,帶給人的新奇感也越來越多。H5頁面從一開始只有展示型,發展到現在多樣的

mui開發appplusreadyinit區別

除了function定義函式之外,全都寫在plusReady之中,function呼叫也放在其中,畢竟做app開發呼叫html5+api十分的頻繁,就像jq的$(document).ready()一樣的道理,尤其是出現plus物件的一定放在plusReady裡面!

微信小程式框架製作-第08課-App.json-window(子)頁面配置講解

pages 用於指定小程式由哪些頁面組成,每一項都對應一個頁面的 路徑+檔名 資訊。檔名不需要寫檔案字尾,框架會自動去尋找對於位置的 .json, .js, .wxml, .wxss 四個檔案進行處理。 陣列的第一項代表小程式的初始頁面(首頁)。小程式中新增/減少頁

NativeH5兩種情況的頭像上傳

最近的工作中接觸了一個小的功能,上傳頭像。上傳頭像是很多應用中的東西,描述下自己的應用。上傳頭像應用的地方: 1.最開始進入app的時候會提示註冊,然後就會呼叫。 2.成功的註冊完畢以後,可以在個人資訊裡面修改頭像。 3.在H5(某個WebView)中也可以修改

iOS原生與H5頁面互動

一、原生框架<JavaScriptCore/JavaScriptCore> (1)JavaScriptCore: 是一種JavaScript引擎,主要為webKit提供指令碼處理能力,可以JS呼叫OC,也可以OC呼叫JS;   (2) JSContext: 代表