客户端相关知识学习(三)之Android原生与H5交互的实现
Android原生與H5交互的實現
H5調用原生的方式
方式可能有多種,根據開發經驗,接觸過兩種方式。
方法一:Android向H5注入全局js對象,也就是H5調Android
1.首先對WebView進行初始化
| WebSettings settings = webview.getSettings(); settings.setJavaScriptEnabled(true); //允許在WebView中使用js |
2.創建一個類JavaScriptMetod,專門用來給js提供可調用的方法
3.創建該類的構造方法,提供兩個參數,WebView對象和上下文對象
| private Context mContext; private WebView mWebView; public JavaScriptMethod(Context context, WebView webView) { mContext = context; mWebView = webView; } |
4.創建一個字符串常量,作為android與js通信的接口,即字符串映射對象
| public static final String JAVAINTERFACE = "javaInterface"; |
5.接下來就是創建給js調用的方法,方法的參數接收一個json字符串(注意:在Android4.2之后,為了提高代碼安全性,方法必須使用注解@JavascriptInterface,否則無法調用)
| @JavascriptInterface //andorid4.2(包括android4.2)以上,如果不寫該注解,js無法調用android方法 public void showToast(String json){ Toast.makeText(context, json, Toast.LENGTH_SHORT).show(); } |
6.在WebView初始化代碼中執行如下代碼
| //創建上面創建類的對象 JavaScriptMetod m = new JavaScriptMetod(this, webview); //其實就是告訴js,我提供給哪個對象給你調用,這樣js就可以調用對象里面的方法 //第二個參數就是該類中的字符串常量 webview.addJavascriptInterface(m, JavaScriptMetod.javaInterface); 現在,在js中就可以調用JavaScriptMetod中的方法了,調用方式如下 //參數一般為json格式 var json = {"name":"javascript"}; //javaInterface是上面所說的字符串映射對象 window.javaInterface.showToast(JSON.stringify(json)); |
網絡上介紹js與android原生交互的文章里,大部分都是上面這種方式,但是這種方式并不適用于ios,也就是說,window.javaInterface.showToast(JSON.stringify(json))這樣的js代碼并不適用于ios,如果用以上的方法,就得分別為android和ios各
寫一套js代碼。這樣很顯然是不太合理的,所以在實際開發中,一般都使用接下來的第二種方法。
方法二:H5發起自定義協議請求,Android攔截請求,再由Android調用H5中的回調函數
這種方法實現的思想是js發出一個url請求,并將所需的參數添加到該url中。android端通過webView.setWebViewClient()攔截url,解析url中攜帶的參數,并根據參數信息進行相應的操作。
1.與方法一相同,首先都需要對webview進行初始化
| WebSettings settings = webview.getSettings(); settings.setJavaScriptEnabled(true); //允許在WebView中使用js? |
2.首先看js中的代碼是怎么寫的
| $("#showtoast").click(function () { var json = {"data": "I am a toast"}; window.location.href="protocol://android?code=toast&data="+JSON.stringify(json); }); $("#call").click(function () { var json = {"data": "10086"}; window.location.href="protocol://android?code=call&data="+JSON.stringify(json); }); |
這里定義兩個點擊事件,分別控制android顯示toast和打電話的操作。其中,protocol://android為自定義的H5與android間的通信協議,與http請求進行區分。code規定了要進行的操作,data為傳輸的數據。
3.android中的代碼
| webView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { /** * 通過判斷攔截到的url是否含有pre,來辨別是http請求還是調用android方法的請求 */ String pre = "protocol://android"; if (!url.contains(pre)) { //該url是http請求,用webview加載url return false; } //該url是調用android方法的請求,通過解析url中的參數來執行相應方法 Map map = getParamsMap(url, pre); String code = map.get("code"); String data = map.get("data"); parseCode(code, data); return true; } }); |
其中,getParamsMap()方法從攔截到的url解析出code,data參數,parseCode()方法將根據不同的code進行相應的操作,代碼如下:
| private Map getParamsMap(String url, String pre) { ArrayMap queryStringMap = new ArrayMap<>(); if (url.contains(pre)) { int index = url.indexOf(pre); int end = index + pre.length(); String queryString = url.substring(end + 1); String[] queryStringSplit = queryString.split("&"); String[] queryStringParam; for (String qs : queryStringSplit) { if (qs.toLowerCase().startsWith("data=")) { //單獨處理data項,避免data內部的&被拆分 int dataIndex = queryString.indexOf("data="); String dataValue = queryString.substring(dataIndex + 5); queryStringMap.put("data", dataValue); } else { queryStringParam = qs.split("="); String value = ""; if (queryStringParam.length > 1) { //避免后臺有時候不傳值,如“key=”這種 value = queryStringParam[1]; } queryStringMap.put(queryStringParam[0].toLowerCase(), value); } } } return queryStringMap; } private void parseCode(String code, String data) { if(code.equals("call")) { try { JSONObject json = new JSONObject(data); String phone = json.optString("data"); //執行打電話的操作,具體代碼省略 PhoneUtils.call(this, phone); } catch (JSONException e) { e.printStackTrace(); } return; } if(code.equals("toast")) { try { JSONObject json = new JSONObject(data); String toast = json.optString("data"); Toast.makeText(this, toast, Toast.LENGTH_SHORT).show(); } catch (JSONException e) { e.printStackTrace(); } return; } } |
最后,特別說明一下shouldOverrideUrlLoading()方法的返回值問題,該方法的返回值有三種:
-
返回true,即根據代碼邏輯執行相應操作,webview不加載該url;
-
返回false,除執行相應代碼外,webview加載該url;
-
返回super.shouldOverrideUrlLoading(),點進父類中,我們可以看到,返回的還是false。
轉載于:https://www.cnblogs.com/kunmomo/p/11556135.html
總結
以上是生活随笔為你收集整理的客户端相关知识学习(三)之Android原生与H5交互的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 客户端相关知识学习(二)之h5与原生ap
- 下一篇: 客户端相关知识学习(四)之H5页面如何嵌