上一篇简单介绍了Androi与前端H5 js的交互方式,那些方式对于一些简单的交互足够了,但是如果涉及到复杂的交互就很乏力,下面就来介绍一个Github上用来处理Android与js较复杂的交互的框架。
框架地址:
https://github.com/jesse01/WebViewJavascriptBridge
步骤:
- 下载代码,找到WebViewJavascriptBridge文件夹,注意这个文件夹下有清单文件,层级不要弄错。
- 在已有的工程中将这个项目以module的形式导入到AS中(框架使用ES编写的),如图
项目结构:
首先看assets文件夹下的html文件和txt文件,txt文件全是js代码,主要用来搭建与java交互的桥梁,不需要管,后面会提到。html文件中包含于java交互的代码。
WVJBWebViewClient也是用来搭建桥梁的不需要细看。只需要看一下onPageFinished方法,这里会加载上面的txt文件,在java中执行txt中的js代码,构建桥梁
@Override public void onPageFinished(WebView view, String url) { try { InputStream is = webView.getContext().getAssets() .open("WebViewJavascriptBridge.js.txt"); int size = is.available(); byte[] buffer = new byte[size]; is.read(buffer); is.close(); String js = new String(buffer); executeJavascript(js); } catch (IOException e) { e.printStackTrace(); } if (startupMessageQueue != null) { for (int i = 0; i < startupMessageQueue.size(); i++) { dispatchMessage(startupMessageQueue.get(i)); } startupMessageQueue = null; } super.onPageFinished(view, url); } public void executeJavascript(String script) { executeJavascript(script, null); } public void executeJavascript(String script, final JavascriptCallback callback) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { webView.evaluateJavascript(script, new ValueCallback<String>() { @Override public void onReceiveValue(String value) { if (callback != null) { if (value != null && value.startsWith("\"") && value.endsWith("\"")) { value = value.substring(1, value.length() - 1) .replaceAll("\\\\", ""); } callback.onReceiveValue(value); } } }); } else { if (callback != null) { myInterface.addCallback(++uniqueId + "", callback); webView.loadUrl("javascript:window." + kInterface + ".onResultForScript(" + uniqueId + "," + script + ")"); } else { webView.loadUrl("javascript:" + script); } } }
上面会根据不通过的Android系统版本使用不同的方法来执行这些js代码。
交互
这里为了看起来清楚,把英文提示改成了汉字
JAVA→JS
第一种方式:
JAVA代码findViewById(R.id.button1).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { webViewClient.send("来自java的数据", new WVJBWebViewClient.WVJBResponseCallback() { @Override public void callback(Object data) { Toast.makeText(MainActivity.this, "js接收到数据并返回数据: " + data, Toast.LENGTH_LONG).show(); } }); } });
JS代码
bridge.init(function(message, responseCallback) { log('JS收到数据', message) var data = { 'js接收到消息了':'啦啦!' } log('JS返回数据', data) responseCallback(data) })
这种方式java传过来的参数都会统一调用bridge.init()中设置的回调方法的方法。可以在这里对message进行判断类型,执行不同的操作。
第二种方式:
JAVA代码
findViewById(R.id.button2).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { try { webViewClient.callHandler("javaCallJs", new JSONObject("{\"java的问候\": \"你好, JS!\" }"), new WVJBWebViewClient.WVJBResponseCallback() { @Override public void callback(Object data) { Toast.makeText(MainActivity.this, "来自js的回应:" + data, Toast.LENGTH_LONG).show(); } }); } catch (JSONException e) { e.printStackTrace(); } } });
JS代码
bridge.registerHandler('javaCallJs', function(data, responseCallback) { log('java调用action javaCallJs', data) var responseData = { 'js收到':'哇呜' } log('JS的响应', responseData) responseCallback(responseData) })
效果图
这种方式是专门的在js中注册一个action,在java中callHandler方法,传入action,调用专门的js方法。对于比较复杂交互来说代码还是比较清楚明了的。
JS→JAVA
第一种方式:
JAVA代码
super(webView, new WVJBWebViewClient.WVJBHandler() { @Override public void request(Object data, WVJBResponseCallback callback) { Toast.makeText(MainActivity.this, "接到js的数据: " + data, Toast.LENGTH_LONG).show(); callback.callback("收到了你的问候,Js"); } });
JS代码
var button = document.getElementById('buttons').appendChild(document.createElement('button')) button.innerHTML = '调用java并传数据' button.onclick = function(e) { e.preventDefault() var data = '你好啊, Java' log('JS发送消息给java', data) bridge.send(data, function(responseData) { log('来自java的回应', responseData) }) }
效果图
和java调用js第一种方式一样,这个会统一调用,通过message的类型进行判断进行不同的操作
第二种方式:
JAVA代码
registerHandler("jsCallJava", new WVJBWebViewClient.WVJBHandler() { @Override public void request(Object data, WVJBResponseCallback callback) { Toast.makeText(MainActivity.this, "收到Js的数据 " + data, Toast.LENGTH_LONG).show(); callback.callback("收到你问候,谢谢!)"); } });
JS代码
var callbackButton = document.getElementById('buttons').appendChild(document.createElement('button')) callbackButton.innerHTML = '调用java注册的action并传数据' callbackButton.onclick = function(e) { e.preventDefault() log('JS调用java action "jsCallJava"') bridge.callHandler('jsCallJava', {'Js的问候': '你好,java!'}, function(response) { log('JS收到java的响应', response) }) }
效果图
这种方式是在java中注册了action,在js中调用action。对于复杂的情况比较合适。
对于这个框架就简单的介绍到这,下一篇将会对这一框架进行封装,达到在html中直接引用一个js文件就实现专门的action。