android_jsbridge,让你和前端愉快的交互
生活随笔
收集整理的這篇文章主要介紹了
android_jsbridge,让你和前端愉快的交互
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
android_js
前言
作為開發人員都知道,客戶端的版本更新對于用戶來說代價是很大的。為了滿足客戶端能夠快速更新迭代的要求,許多app都內嵌入了H5,比如很多電商平臺,淘寶、京東、 聚劃算等等。這類技術的關鍵就是在于Android客戶與Web前端之間的交互。很多大型項目的接口為了防止Spammer的侵入,都是要求只能由客戶端發起請求的。所以本項目 就封裝了一個module,實現客戶端接收前端的調用,然后由客戶端發起Http請求的功能。 復制代碼 開始介紹項目之前,先來快速回顧一下Android客戶端與Web前端之間交互的幾種方式。 復制代碼1. Android調用JS方法
1.1 通過WebView的loadUrl()
android客戶端代碼:
private void initWebView() {WebSettings webSettings = webView.getSettings();webSettings.setJavaScriptEnabled(true); // 設置與Js交互的權限webSettings.setJavaScriptCanOpenWindowsAutomatically(true); // 設置允許JS彈窗webView.loadUrl("file:///android_asset/javascript.html");webView.setWebChromeClient(new WebChromeClient() {@Overridepublic boolean onJsAlert(WebView view, String url, String message, final JsResult result) {AlertDialog.Builder b = new AlertDialog.Builder(SimpleWebViewActivity.this);b.setTitle("Alert");b.setMessage(message);b.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {result.confirm();}});b.setCancelable(false);b.create().show();return true;}}); }private void setListener() {btnLoadUrl.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {webView.post(new Runnable() {@Overridepublic void run() {// 此處的callJS方法名與JS中的function方法名必須要一致webView.loadUrl("javascript:callJS()");}});}}); } 復制代碼javascript前端代碼:
<!DOCTYPE html><html><head><meta charset="utf-8"><title>Carson_Ho</title>// JS代碼<script>// Android需要調用的方法function callJS() {alert("Android調用了JS的callJS方法");}</script></head></html> 復制代碼 運行結果如圖 復制代碼 ? ? android客戶端代碼: btnEvaluateJavascript.setOnClickListener(new View.OnClickListener() {@TargetApi(19)@Overridepublic void onClick(final View v) {webView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() {@Overridepublic void onReceiveValue(String value) {//此處為 js 返回的結果Log.d(TAG, "value---" + value);}});}}); 復制代碼 運行結果跟上圖是一樣的。 復制代碼 兩種交互方式的比較 復制代碼| 使用loadUrl() | 方便簡潔 | 效率低;獲取返回值麻煩 | 不需要使用返回值,對性能要求較低 |
| 使用evaluateJavascript() | 效率高 | 向下兼容性差(僅Android 4.4以上可用) | Android 4.4及以上 |
1.3 使用建議
// Android版本變量 final int version = Build.VERSION.SDK_INT; // 因為該方法在 Android 4.4 版本才可使用,所以使用時需進行版本判斷 if (version < 18) {webView.loadUrl("javascript:callJS()"); } else {webView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() {@Overridepublic void onReceiveValue(String value) {//此處為 js 返回的結果}}); } 復制代碼2. JS調用Android方法
2.1 通過WebView的addJavascriptInterface()進行對象映射
代碼不再貼出,詳細代碼請參見:代碼地址 ? ?運行結果如下:
2.2 通過 WebViewClient 的方法shouldOverrideUrlLoading()回調攔截 url
代碼不再貼出,詳細代碼請參見:代碼地址 ? ?運行結果如下:
2.3 通過 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回調攔截JS對話框alert()、confirm()、prompt()消息
代碼不再貼出,詳細代碼請參見:代碼地址 ? ?運行結果如下:
2.3.1 onJsAlert()、onJsConfirm()、onJsPrompt()三者之間的比較
| alert() | 彈出警告框 | 沒有 |
| confirm() | 彈出確認框 | 兩個返回值(true或false) |
| prompt() | 彈出輸入框 | 任意設置返回值 |
2.3.2 總結
常用的攔截是:攔截 JS的輸入框(即prompt()方法),因為只有prompt()可以返回任意類型的值,操作最全面方便、更加靈活, 而alert()對話框沒有返回值,confirm()對話框只能返回兩種狀態(確定 / 取消)兩個值。 復制代碼2.4 三種Android Call Js 方式的對比以及使用場景
| 通過WebView的addJavascriptInterface() 進行對象映射 | 方便簡潔 | Android 4.2以下存在漏洞問題 | Android 4.2以上相對簡單的互調場景 |
| 通過 WebViewClient 的方法shouldOverrideUrlLoading() 回調攔截 url | 不存在漏洞問題 | 有協議約束,客戶端向前端傳值繁瑣 | 不需要返回值的互調場景 |
| 通過 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法 回調攔截JS對話框alert()、confirm()、prompt()消息 | 不存在漏洞問題 | 有協議約束 | 能滿足大多數情況下的互調場景 |
附:WebView的addJavascriptInterface()方法在Android 4.2以下存在的漏洞
以上都是對基礎知識的回顧,下面的才是本項目的解釋說明。注意了,以下才是本項目的解釋說明!!
先來看一下項目運行的效果圖: 復制代碼 大家會說,這個不是跟攔截JS的prompt()方法一樣么,沒錯,js和android之間的交互,也無非上面提到的幾種方法,這里做的封裝采用的是: js調android:通過WebView的addJavascriptInterface()進行對象映射 android回調js:android 4.4以上采用WebView的evaluateJavascript()方法,android 4.4以下采用loadUrl()方法 復制代碼 android端代碼: 復制代碼JsBridgeWebView 這是一個繼承WebView的類,它里面向JS注入了一個對象供JS調用,JS可以通過這個對象調用Native的方法,調哪個方法,傳哪些參數,完全由JS決定,方法名必須兩端協議,Native通過反射找到對應的方法。傳遞過來的參數重包含了JS回調方法的方法名,客戶端執行完相應的操作之后再去執行JS的方法。
js代碼: <!DOCTYPE html> <html> <head><meta charset="utf-8"><title>Carson</title><script>function callAndroid(){// 由于對象映射,所以調用jsCallback對象等于調用Android映射的對象var json = "{\"name\": \"zlove\", \"_dscbstub\": \"callback\"}"_jsbridge.call("testAsync", json);}function callback(result) {alert("客戶端返回的結果是:" + result)}</script> </head> <body> <!-- 點擊按鈕則調用callAndroid函數 --> <button type="button" id="button1" style="font-size:30px" onclick="callAndroid()">Call Android</button> </body> </html> 復制代碼 var json = "{\"name\": \"zlove\", \"_dscbstub\": \"callback\"}" _jsbridge.call("testAsync", json); _jsbridge表示客戶端注入的對象,testAsync是方法名,json是參數,而_dscbstub對應的callback是js的回調方法。 復制代碼end
本來以為要寫很多,事實上其實把基礎原理寫清楚了,也就這么多???。 I hope this will help you! 復制代碼附:源碼地址
總結
以上是生活随笔為你收集整理的android_jsbridge,让你和前端愉快的交互的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 46. Permutations 排列数
- 下一篇: mybatis @sqlprovide