h5和原生结合开发app越来越流行。其实就是webview 的js调用native的方法。也就是需要搭建一个桥。这样的桥早就有人搭建好了,那就是jsbridge。
git地址:
其实很简单,那些添加依赖我就不说了。
两种情况:
1.js调用本地的方法:webView.loadUrl("http://testopen.cebbank.com/LifePayment/wap/apph5/index.html?uid=111&token=65F34B3203D893AD96173918C80C45B3&telno=16578915632&type=0&canal=yaoyaoshenghuo1&version=1.0.0&macValue=1167DA1CDF6379B94914C8CB5099542C"); webView.registerHandler("wxpay", new BridgeHandler() { @Override public void handler(String data, CallBackFunction function) {// Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show(); Gson gson = new GsonBuilder()// 2013-09-14 16:45:29 .setDateFormat("yyyy-MM-dd HH:mm:ss")// .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") .create(); OrderModel ordermodel=gson.fromJson(data,OrderModel.class); requestWXPay(MainActivity.this,ordermodel); Log.i(TAG, "handler: "+ordermodel.getAppid()); Log.i(TAG, "handler = submitFromWeb, data from web = " + data);// function.onCallBack("submitFromWeb exe, response data 中文 from Java"); } });
js里面这样写:
//call native method window.WebViewJavascriptBridge.callHandler( 'wxpay' //, {'param': '中文测试'} , data.orderModel , function(responseData) { } );
- 本地给js发送消息, 调用网页的方法: 本地这样写;
webView.callHandler("payResult", state, new CallBackFunction() { @Override public void onCallBack(String data) { // TODO Auto-generated method stub// Log.i(TAG, "reponse data from js " + data); } });
js里面这样写:
function connectWebViewJavascriptBridge(callback) { if (window.WebViewJavascriptBridge) { callback(WebViewJavascriptBridge) } else { document.addEventListener( 'WebViewJavascriptBridgeReady' , function() { callback(WebViewJavascriptBridge) }, false ); } } connectWebViewJavascriptBridge(function(bridge) { bridge.init(function(message, responseCallback) { console.log('JS got a message', message); var data = { 'Javascript Responds': '测试中文!' }; console.log('JS responding with', data); responseCallback(data); }); bridge.registerHandler("payResult", function(data, responseCallback) { alert(data); document.getElementById("show").innerHTML = ("data from Java: = " + data); var responseData = "Javascript Says Right back aka!"; responseCallback(responseData); }); })
就是一句户,方法名称对的上就可以了。
我这里只是总结了一下,其他的基础东西,自己看githup.使用jsbridge遇到ssl认证的网站,结果一片空白。也就是https开头的。比如银联支付的页面。那么一开始我就设置了一个处理的webview,
WebViewClient webviewclient=new WebViewClient(){ @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { handler.proceed(); } }; webView.setWebViewClient(webviewclient);
后来,这个webview可以访问银联这种ssl认证的参数,但是不能响应js的调用了。
一直报错:"Uncaught TypeError: Cannot call method 'callHandler' of undefined", source
我就知道jsbridge肯定自己设置了一个自己的webviewlicent,查看源码库,找到了:
package coma.github.lzyzsd.jsbridge; private void init() { this.setVerticalScrollBarEnabled(false); this.setHorizontalScrollBarEnabled(false); this.getSettings().setJavaScriptEnabled(true); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { WebView.setWebContentsDebuggingEnabled(true); } this.setWebViewClient(generateBridgeWebViewClient()); } protected BridgeWebViewClient generateBridgeWebViewClient() { return new BridgeWebViewClient(this); }
这里,然后这个BridgeWebViewClient我们需要重写,让他支持ssl:
package coma.github.lzyzsd.jsbridge;import android.graphics.Bitmap;import android.net.http.SslError;import android.webkit.SslErrorHandler;import android.webkit.WebView;import android.webkit.WebViewClient;import java.io.UnsupportedEncodingException;import java.net.URLDecoder;/** * Created by bruce on 10/28/15. */public class BridgeWebViewClient extends WebViewClient { private BridgeWebView webView; public BridgeWebViewClient(BridgeWebView webView) { this.webView = webView; } @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { handler.proceed(); }
ok,既可以使用js,也可以支持ssl。