前端菜菜一枚,写下关于h5 和native 交互那些事情。偏前端,各种理论知识,不在赘述。之前有各位大牛已经写过。我只写代码,有问题,下面留言
/* 关于h5 和native 之间的交互 JSBridge 解决问题,偏向前端* 使用URL 拦截方式,借用iframe *//*** ios,使用自有shouldStartLoadWithRequest 方法* 安卓:shouldOverrideUrlLoading* html5:挂载到window 对象上* */复制代码
html5部分:
dom:<button onclick="showLoading()"> showLoading</button><button onclick="closeLoading()"> closeLoading</button><button onclick="showAlert()">showAlert</button><button onclick="toast()">toast</button><button onclick="pending_payment()">pending_payment</button>script:var bridge = {'linkNative': function (func, type, params, callback) {var funcId = 'cb_' + +new Date()window[funcId] = callback || function () { }params = params || {}var req = {handler: func,params: params || undefined,callback: callback && funcId}var src = 'test://' + type + '?' + JSON.stringify(req)var frag = document.createElement('iframe')frag.style.display = 'none'frag.src = srcdocument.body.appendChild(frag);setTimeout(function () {document.body.removeChild(frag)}, 1000)},'showLoading': function () {this.linkNative('showLoading', 'functional')return this},'closeLoading': function () {this.linkNative('closeLoading', 'functional')return this},'showAlert': function (params) {this.linkNative('showAlert', 'functional', params)},'toast': function (params) {this.linkNative('toast', 'functional', params)return this},// 发起支付请求'pending_payment': function (params, callback) {this.linkNative('pending_payment', 'business', params, callback)}}//开启loadingfunction showLoading() {console.log('a')bridge.showLoading()}function closeLoading() {bridge.closeLoading()}function showAlert() {bridge.showAlert('我点击了showAlert')}function toast() {var params = {data: "我是toast"}bridge.toast(params)}function pending_payment() {var params = {orderId: '12uroi2u4oifjidsafj',time: '1234234392483294829',name: '张三'}bridge.pending_payment(params, function () {bridge.showAlert('支付的回调函数')//其他业务代码})}复制代码
这是在和native端约定好的协议和方法 test,functional,buness
复制代码
参考:https://juejin.im/post/5bda6f276fb9a0226d18931f
安卓demo:
JSonUtils.java
package com.example.zhangyuke.mywebview;import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;import com.alibaba.fastjson.JSONObject;public class MainActivity extends AppCompatActivity {private static final String TAG = "MainActivity";private WebView wb;private String URL_HOST_STARTWITH_FUNCATIONAL = "test://functional";private String URL_HOST_STARTWITH_BUSINSS = "test://business";private String URL_QUERY_KEY_HANDLER = "handler";private String URL_SHOW_LOADING = "showLoading";private String URL_CLOSE_LOADING = "closeLoading";private String URL_SHOW_ALERT="showAlert";private String URL_TOAST="toast";private String URL_PENDING_PAYMENT="pending_payment";private String URL_QUERY_KEY_CALLBACK="callback";private String URL_QUERY_PARAMS="params";private String URL_DATA="data";private String ORDER_ID="orderId";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);wb = findViewById(R.id.wb);//支持js语言wb.getSettings().setJavaScriptEnabled(true);//缩放至屏幕的大小wb.getSettings().setLoadWithOverviewMode(true);//支持缩放wb.getSettings().setSupportZoom(true);//webview去加载网页wb.loadUrl("http://www.jiaxinying.cn./bridge/");//设置用自己的浏览器打开wb.setWebViewClient(new MyWebViewClient());}private boolean baseParseShouldOverrideUrlLoading(WebView view, String url, Uri uri) {if (url.startsWith(URL_HOST_STARTWITH_FUNCATIONAL)) {JSONObject queryObject = JSonUtils.parseObjectWithoutException(uri.getQuery());String jsCallback = queryObject.getString(URL_QUERY_KEY_CALLBACK);String action = queryObject.getString(URL_QUERY_KEY_HANDLER);Log.d(TAG, "test://functional: handler: " + action);if (URL_SHOW_LOADING.equals(action)) {Toast.makeText(this, "加载进度条", Toast.LENGTH_SHORT).show();return true;} else if (URL_CLOSE_LOADING.equals(action)) { // 设置标题Toast.makeText(this, "关闭进度条", Toast.LENGTH_SHORT).show();return true;}else if (URL_SHOW_ALERT.equals(action)){String params = queryObject.getString(URL_QUERY_PARAMS);if (!TextUtils.isEmpty(params)) {Toast.makeText(this, params, Toast.LENGTH_SHORT).show();}}else if (URL_TOAST.equals(action)){String params = queryObject.getString(URL_QUERY_PARAMS);if (!TextUtils.isEmpty(params)){JSONObject paramsObject=JSonUtils.parseObjectWithoutException(params);if (paramsObject!=null){String data = paramsObject.getString(URL_DATA);Toast.makeText(this, data, Toast.LENGTH_SHORT).show();}}}} else if (url.startsWith(URL_HOST_STARTWITH_BUSINSS)){JSONObject queryObject = JSonUtils.parseObjectWithoutException(uri.getQuery());String jsCallback = queryObject.getString(URL_QUERY_KEY_CALLBACK);String action = queryObject.getString(URL_QUERY_KEY_HANDLER);if (URL_PENDING_PAYMENT.equals(action)){String params = queryObject.getString(URL_QUERY_PARAMS);if (!TextUtils.isEmpty(params)){JSONObject paramsObject=JSonUtils.parseObjectWithoutException(params);if (paramsObject!=null){String order = paramsObject.getString(ORDER_ID);
// Toast.makeText(this, order, Toast.LENGTH_SHORT).show();}}callBackToJs(jsCallback,"");}}return false;}//js回调private void callBackToJs(String callbackFunc, String callbackParam) {if (TextUtils.isEmpty(callbackFunc)) {Log.e(TAG,"callback Func is Null");} else {wb.loadUrl("javascript:" + callbackFunc + "(" + callbackParam + ")");}}class MyWebViewClient extends WebViewClient {@Overridepublic boolean shouldOverrideUrlLoading(WebView view, String url) {Log.i(TAG,"webView shouldOverrideUrl: " + url);Uri uri = Uri.parse(url);return baseParseShouldOverrideUrlLoading(view, url, uri);}}}
复制代码
MainActivity.java
package com.example.zhangyuke.mywebview;import android.util.Log;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;import java.text.DateFormat;
import java.util.logging.Logger;/*** Created by zhangyuke on 2018/11/6.*/public final class JSonUtils {private static final String TAG = JSonUtils.class.getSimpleName();private JSonUtils() {//Utility classes should not have a public or default constructor.}public static <T> T parseObjectWithoutException(String text, Class<T> clazz) {try {return JSON.parseObject(text, clazz);} catch (Exception ex) {Log.e(TAG, "parseObjectWithoutException, exception = " + ex.getMessage());return null;}}public static JSONObject parseObjectWithoutException(String text) {try {return JSON.parseObject(text);} catch (Exception ex) {Log.e(TAG, "parseObjectWithoutException, exception = " + ex.getMessage());return null;}}
}
复制代码
最后,感谢我司阿珂。提供安卓demo文档。