1. 概述
为加快项目开发效率,相信绝大部分公司都会采用H5与Native原生结合开发,使用H5去开发一些功能,这里肯定会涉及到Android与Js互相调用的问题,这里有2种方式,第一种是使用原生的addJavascriptInterface()来解决,不过存在一定的风险,有一种比较安全的方式来满足二者互调的问题,就是我们今天所要讲解的一个新的东西,WebViewJavascriptBridge。
如果对addJavascriptInterface方式不太了解的,可以看下我之前写的文章
Android与Js互调之 - 使用addJavascriptInterface()
2. WebViewJavascriptBridge定义是什么?
WebViewJavascriptBridge是Java与Js互相调用的桥梁,替代了WebView中自带的addJavascriptInterface接口,使得Java与Js交互更加灵活,也使得开发会更加安全。
3. 具体实现如下
这里没有直接使用 最原生的BridgeWebView,而是 基于JsBridge封装的高效的自带加载进度条的WebView,当然这个东西不是我自己封装的,我只是在网上找的一个大神的文章,然后自己手动的添加一些注释,有利于我们大家来更清楚的知道其中的用法,其实很简单,因为大神已经把其封装的很好了,然后我们这边需要做的就是直接仿照它里边是怎样写的就ok了,以下是大神博客,想详细了解的可以移步这里:
Android基于JsBridge封装的高效带加载进度的WebView
下边我就直接贴出具体代码,大家直接看下就ok,其中注释也是有的,里边有我们平时开发中所需要的一些东西
/**
* Email: 2185134304@qq.com
* Create JackChen 2018/4/3 11:11
* Version:
* Params:
* Description: 基于JsBridge封装的高效自带加载进度条的WebView
*/
public class MainActivity extends AppCompatActivity {
// WebView
private ProgressBarWebView mProgressBarWebView;
// 用于存放Js代码中的所有方法名
private ArrayList<String> mHandlers = new ArrayList<>();
ValueCallback<Uri> mUploadMessage;
private static CallBackFunction mfunction;
int RESULT_CODE = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initWebView();
}
private void initWebView() {
mProgressBarWebView = (ProgressBarWebView) findViewById(R.id.login_progress_webview);
mProgressBarWebView.setWebViewClient(new CustomWebViewClient(mProgressBarWebView.getWebView()) {
@Override
public String onPageError(String url) {
//指定网络加载失败时的错误页面
return "file:///android_asset/error.html";
}
@Override
public Map<String, String> onPageHeaders(String url) {
// 可以加入header
return null;
}
@SuppressWarnings("unused")
public void openFileChooser(ValueCallback<Uri> uploadMsg, String AcceptType, String capture) {
this.openFileChooser(uploadMsg);
}
@SuppressWarnings("unused")
public void openFileChooser(ValueCallback<Uri> uploadMsg, String AcceptType) {
this.openFileChooser(uploadMsg);
}
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
mUploadMessage = uploadMsg;
pickFile();
}
});
// 打开页面,也可以支持网络url
mProgressBarWebView.loadUrl("file:///android_asset/demo.html");
mHandlers.add("login");
mHandlers.add("callNative");
mHandlers.add("callJs");
mHandlers.add("open");
//回调js的方法 handlerName:Js中写的方法 responseData:Js返回的数据 function.onCallBack("我在上海"):回调给Js的数据
mProgressBarWebView.registerHandlers(mHandlers, new JsHandler() {
@Override
public void OnHandler(String handlerName, String responseData, CallBackFunction function) {
// 点击WebView中 登录 (Js中定义的login()方法)
if (handlerName.equals("login")) {
Toast.makeText(MainActivity.this, responseData, Toast.LENGTH_SHORT).show();
} else if (handlerName.equals("callNative")) {
Toast.makeText(MainActivity.this, responseData, Toast.LENGTH_SHORT).show();
function.onCallBack("我在上海");
// 点击调用native
} else if (handlerName.equals("callJs")) {
Toast.makeText(MainActivity.this, responseData, Toast.LENGTH_SHORT).show();
// 想调用你的方法:
function.onCallBack("好的 这是图片地址 :xxxxxxx");
// 点击选择相册
} if (handlerName.equals("open")) {
mfunction = function;
pickFile();
}
}
});
// 首先显示WebView,然后调用Js中的callNative()方法,jsResponseData是Js返回来的数据
mProgressBarWebView.callHandler("callNative", "hello H5, 我是java", new JavaCallHandler() {
@Override
public void OnHandler(String handlerName, String jsResponseData) {
Toast.makeText(MainActivity.this, "h5返回的数据:" + jsResponseData, Toast.LENGTH_SHORT).show();
}
});
//发送消息给js
mProgressBarWebView.send("哈喽", new CallBackFunction() {
@Override
public void onCallBack(String data) {
Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show();
}
});
}
public void pickFile() {
Intent chooserIntent = new Intent(Intent.ACTION_GET_CONTENT);
chooserIntent.setType("image/*");
startActivityForResult(chooserIntent, RESULT_CODE);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == RESULT_CODE) {
if (null == mUploadMessage) {
return;
}
Uri result = intent == null || resultCode != Activity.RESULT_OK ? null : intent.getData();
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
mfunction.onCallBack(intent.getData().toString());
}
}
@Override
public void onDestroy() {
super.onDestroy();
// 防止内存泄露
if (mProgressBarWebView.getWebView() != null) {
mProgressBarWebView.getWebView().destroy();
}
}
}
具体代码已上传至github:
https://github.com/shuai999/WebViewJavascriptBridge.git