前言
- 现在很多App都选择混合开发模式,即App内置Web网页(Hybrid App),比如说很多电商平台,淘宝、京东、聚划算等等
- App中加载网页是由Android的WebView实现的,其中涉及到Android客户端与Web网页交互的实现
- 下面是对 Android通过WebView与JS交互 的总结
1. 交互方式总结
Android与JS通过WebView互相调用的方法,实际上是:
- Android去调用JS的代码
- JS去调用Android的代码
二者沟通的桥梁是WebvView
Android调用JS代码的方法有2种:
- 通过
WebView
的loadUrl()
方法 - 通过
WebView
的evaluateJavascript
方法
JS调用Android代码的方法有3种:
- 通过
WebView
的addJavascriptInterface()
进行对象映射 - 通过
WebViewClient
的shouldOverrideUrlLoading ()
方法回调拦截 url - 通过
WebViewClient
的onJsAlert()
、onJsConfirm()
、onJsPrompt()
方法回调拦截JS对话框的alert()
、confirm()
、prompt()
消息
2. 具体分析
2.1 Android 通过 WebView 调用 JS 代码
对于Android调用JS代码的方法有2种:
- 通过
WebView
的loadUrl()
方法 - 通过
WebView
的evaluateJavascript
方法
2.1.1 方法分析
方式1:通过 WebView
的 loadUrl()
方法
- 实例介绍:点击Android按钮,即调用 WebView JS(文本名为
javascript
)中 callJS() - 具体使用:
步骤1:将需要调用的JS代码以.html
格式放到src/main/assets文件夹里
- 为了方便展示,本文是采用Andorid调用本地JS代码说明;
- 实际情况时,Android更多的是调用远程JS代码,即将加载的JS代码路径改成url即可
需要加载JS代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
// JS代码
<script>
// Android需要调用的方法
function callJS(){
alert("Android调用了JS的callJS方法");
}
</script>
</head>
<body>
<h1>你好!我是网页</h1>
</body>
</html>
步骤2:在Android里通过WebView设置调用JS代码
这里我继承了BaseActivty ,里面封装了一些初始化的东西,实际上就是在 onCreate() 里初始化 initView()
public class WebViewActivity extends BaseActivty {
@BindView(R.id.webview)
WebView webview;
@Override
protected int getLayoutResId() {
return R.layout.activity_webview;
}
@Override
protected void initView() {
WebSettings webSettings = webview.getSettings();
// 设置与Js交互的权限
webSettings.setJavaScriptEnabled(true);
// 设置允许JS弹窗
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
//设置自适应屏幕,两者合用
webSettings.setUseWideViewPort(true); //将图片调整到适合webview的大小
webSettings.setLoadWithOverviewMode(true);// 缩放至屏幕的大小
// webview只是载体,内容的渲染需要使用webviewChromClient类去实现,
// 通过设置WebChromeClient对象处理JavaScript的对话框,不设置的话,网页对话框出不来
webview.setWebChromeClient(new CustomWebViewChromeClient());
webview.loadUrl("file:///android_asset/test_image.html");
}
@Override
protected void setListener() {
}
@Override
protected void processLogic() {
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// TODO: add setContentView(...) invocation
ButterKnife.bind(this);
}
@OnClick({
R.id.button1, R.id.button2, R.id.button3, R.id.button4})
void onClick(View view) {
switch (view.getId()) {
case R.id.button1:
webview.loadUrl("javascript:callJS()");
break;
default:
}
}
public class CustomWebViewChromeClient extends WebChromeClient {
//设置响应js 的Alert()函数
/**
* 拦截js的警告框,没有返回值
*
* @param view
* @param url 网页地址
* @param message 代表 alert()里的内容(不是url)
* @param result
* @return
*/
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
//如不想弹出网页上的对话框,可直接拦截,并自定义对话框
// AlertDialog.Builder builder = new AlertDialog.Builder(WebViewActivity.this);
// builder.setTitle("Alert")
// .setMessage(message)
// .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
// @Override
// public void onClick(DialogInterface dialog, int which) {
// result.confirm();
// }
// })
// .setCancelable(false)
// .create()
// .show();
// return true;
return super.onJsAlert(view, url, message, result);
}
}
}
特别注意:JS代码调用一定要在 onPageFinished() 回调之后才能调用,否则不会调用。
onPageFinished()属于WebViewClient类的方法,主要在页面加载结束时调用
方式2:通过 WebView
的 evaluateJavascript()
方法
- 优点:该方法比第一种方法效率更高、使用简洁。
- 该方法的执行不会使页面刷新,而第一种方法(loadUrl )的执行则会。
- Android 4.4 后才可使用。
具体使用:
// 只需要将第一种方法的loadUrl()换成下面该方法即可
webview.evaluateJavascript("javascript:callJSReturnParams()",
new