Android WebView 与 JS 交互方式
1. 交互方式总结
Android与js通过WebView互相调用方法,实际上是:
Android去调用JS的代码 JS去调用Android的代码 二者沟通的桥梁是WebView 对于android调用JS代码的方法有2种: 1. 通过WebView的loadUrl() 2. 通过WebView的evaluateJavascript()
对于JS调用Android代码的方法有3种: 只能传字符串String
1. 通过WebView的addJavascriptInterface()进行对象映射 2. 通过 WebViewClient 的shouldOverrideUrlLoading ()方法回调拦截 url 3. 通过 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt() 消息
加载JS代码:JavaScript.html
// 文本名:javascript
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Carson</title>
<script>
// Android需要调用的方法
function callAndroid(){
alert("Android调用了JS的callJS方法");
clickObj.hello("js android hello","2222");
}
</script>
</head>
<body>
callAndroid
<button type="button" id="button1" onclick="callAndroid()"></button>
</body>
</html>
步骤2:在Android里通过WebView设置调用JS代码
@SuppressLint("SetJavaScriptEnabled")
private void creatWebView() {
//声明WebSettings子类
WebSettings webSettings = mWebView.getSettings();
//如果访问的页面中要与Javascript交互,则webview必须设置支持Javascript
webSettings.setJavaScriptEnabled(true);
// 通过addJavascriptInterface()将Java对象映射到JS对象
//参数1:Javascript对象名
//参数2:Java对象名 AndroidtoJS类对象映射到js的clickObj对象
mWebView.addJavascriptInterface(new AndroidtoJs(this), "clickObj");
//设置自适应屏幕,两者合用
webSettings.setUseWideViewPort(true); //将图片调整到适合webview的大小
webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小
//缩放操作
webSettings.setSupportZoom(true); //支持缩放,默认为true。是下面那个的前提。
webSettings.setBuiltInZoomControls(true); //设置内置的缩放控件。若为false,则该WebView不可缩放
webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件
//其他细节操作
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE); //关闭webview中缓存
webSettings.setAllowFileAccess(true); //设置可以访问文件
webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通过JS打开新窗口
webSettings.setLoadsImagesAutomatically(true); //支持自动加载图片
webSettings.setDefaultTextEncodingName("utf-8");//设置编码格式
//优先使用缓存:
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
//加载本地路径
mWebView.loadUrl("file:///android_asset/javascript.html");
}
//步骤3. 复写shouldOverrideUrlLoading()方法,使得打开网页时不调用系统浏览器, 而是在本WebView中显示
mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return true;
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
if (!WebActivity.this.isFinishing()) {
dialog.show();
}
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
dialog.dismiss();
}
});
// 由于设置了弹窗检验调用结果,所以需要支持js对话框
// webview只是载体,内容的渲染需要使用webviewChromClient类去实现
// 通过设置WebChromeClient对象处理JavaScript的对话框
// 设置响应js 的Alert()函数
mWebView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
AlertDialog.Builder b = new AlertDialog.Builder(WebActivity.this);
b.setTitle("Alert");
b.setMessage(message);
b.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.confirm();
}
});
b.setCancelable(false);
b.create().show();
return true;
}
});
AndroidtoJs映射方法 JS调用Android方法 写一个类继承Object
public class AndroidtoJs extends Object {
private WebActivity web;
public AndroidtoJs(WebActivity web) {
this.web = web;
}
// 定义JS需要调用的方法
// 被JS调用的方法必须加入@JavascriptInterface注解
@JavascriptInterface
public void click(String msg) {
LogUtil.e("AndroidtoJs---->>>click==" + msg);
try {
JSONObject json = new JSONObject(msg);
// String resCode = json.optString("resCode");
String resMsg = json.optString("resMsg");
String infoId = json.optString("info");
ToastUtil.showSafeToast(resMsg);
if (infoId != null && !infoId.equals("")) {
MsgTipDoInfo msgTipDoInfo = MsgTipUtil.getInstance().queryByInfoId(infoId);
if (msgTipDoInfo != null) {
MsgTipUtil.getInstance().delete(msgTipDoInfo);
web.getApplicationContext().sendBroadcast(new Intent(Contents.ACTION_MESSAGE_REFRESH));
}
web.getApplicationContext().sendBroadcast(new Intent(Contents.ACTION_BROADCAST_REFRESH_APPROVAL));
web.finish();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
@JavascriptInterface
public void hello(String msg, String s) {
LogUtil.e("--->msg==" + msg + "--->s==" + s);
web.getApplicationContext().sendBroadcast(new Intent(Contents.ACTION_BROADCAST_REFRESH_APPROVAL));
web.finish();
}
@JavascriptInterface
public void download(String downUrl, String fileName) {
if (downUrl != null && fileName != null && !downUrl.equals("") && !fileName.equals("")) {
web.down(downUrl, fileName);
}
}
//选择文件
@JavascriptInterface
public void fileUpload(String fileName, String domid) {
LogUtil.e("androidtoJS-->>fileName==" + fileName + "--->>domid=" + domid);
if (fileName != null && fileName.equals("file")) {
web.chooseFile(domid);
} else if (fileName != null && fileName.equals("img")) {
web.select(domid);
}
}
}
Android要调用JS的方法需要单独开线程
mWebView.post(new Runnable() {
@Override
public void run() {
//可以传String参数过去
mWebView.loadUrl("javascript:callAndroid()"); }
});