概述
一、Android通过WebView与JS交互
1.1、android通过WebView调用js代码方法有2中:
- 通过WebView的loadUrl()
- 通过WebView的evaluateJavascript()
1.2、JS通过WebView调用android代码的方式有3中:
- 通过WebView的addJavascriptInterface()进行对象映射
- 通过WebViewClient的shouldOverrideUrlLoading()方法拦截url
- 通过WebChromeClient的onJsAlert(), onJsConfirm(), onJsPrompt()方法回调拦截JS对话框的alert()、confirm()、prompt()消息
二、具体使用:
2.1android通过WebView调用js代码方法
2.1.1通过WebView的loadUrl()
实例介绍:点击Android中的按钮,即调用WebView的JS中的callJS()方法
具体使用:
- 为了方便展示,在src/main/assets文件夹下创建html文件,加载html文件mWebView.loadUrl(file:///android_asset/demo.html)
<html>
<head>
<title>demo</title>
<script>
function callJS(){
alert("Android 调用了js");
}
</script>
</head>
</html>
- Android调用js的代码:
public class WebViewJsActivity extends Activity implements View.OnClickListener {
private WebView mWebView;
private Button mLoadUrlBt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web_view_js);
mLoadUrlBt = findViewById(R.id.load_url);
mLoadUrlBt.setOnClickListener(this);
mWebView = findViewById(R.id.webview_js);
WebSettings settings = mWebView.getSettings();
//加载js代码
settings.setJavaScriptEnabled(true);
mWebView.loadUrl("file:///android_asset/demo.html");
//因为在js中用到了alert(),因此需要设置WebChromeClient()
mWebView.setWebChromeClient(new WebChromeClient());
}
//通过loadurl调用js方法
private void loadUrlToJS(){
// 注意调用的JS方法名要对应上
// 调用javascript的callJS()方法
mWebView.loadUrl("javascript:callJS()");
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.load_url:
loadUrlToJS();
break;
}
}
}
特别注意:JS代码调用一定要在 onPageFinished() 回调之后才能调用,否则不会调用。
onPageFinished()属于WebViewClient类的方法,主要在页面加载结束时调用
2.1.2通过WebView的evaluateJavascript()
- 优点:该方法比第一种方法效率更高、使用更简洁。
- 该方法的执行不会使页面刷新,loadUrl则会
- Android4.4后才可以使用
- 具体使用
//通过evaluateJavascript与js交互
private void evaluateJavascript(){
mWebView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
//value为js返回的结果
}
});
}
建议两种方式混合使用,在android4.4以下用loadUrl,在Android4.4以上用evaluateJavascript()
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT){
mWebView.loadUrl("javascript:callJS()");
}else {
mWebView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
}
});
}
2.2JS通过WebView调用Android代码
2.2.1通过WebView的addJavascriptInterface()进行对象映射
- 定义一个与JS对象映射关系的Android类 MyObject
class MyObject{
// 定义JS需要调用的方法
// 被JS调用的方法必须加入@JavascriptInterface注解
@JavascriptInterface
public void toast(String message){
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
}
2.在js代码中加入
function callToast(){
toast.toast("js调用了Android中的toast方法");
}
3.在Android里通过WebView设置Android类与JS代码的映射
public void addJavascriptInterface(){
mWebView.addJavascriptInterface(new MyObject(), "toast");
}
特点
- 优点:使用简单 仅需要Android对象与JS对象建立映射
- 缺点:存在严重的漏洞
2.2.2通过WebViewClient的shouldOverrideUrlLoading方法拦截Url
- 原理:
Android通过WebViewClient的shouldOverrideUrlLoading方法拦截Url,然后按照约定好的协议解析url,调用对应的方法。
- 使用实例:
- 在JS约定所需要的Url协议
function shouldOverrideUrl(){
document.location = "demo://webview?arg1=1&arg2=2"
}
<button type="button" id="button2" onclick="shouldOverrideUrl()">shouldOverrideUrlLoading</button>
- 在Android里通过WebViewClient覆写shouldOverrideUrlLoading()方法
public void shouldOverrideUrlLoading(){
mWebView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
Uri url = request.getUrl();
if(url.getScheme().equals("demo")){
if(url.getAuthority().equals("webview")){
Set<String> paramNames = url.getQueryParameterNames();
StringBuilder builder = new StringBuilder();
for (String paramName: paramNames){
String value = url.getQueryParameter(paramName);
builder.append(paramName);
builder.append("=");
builder.append(value);
builder.append("; ");
}
Log.d("WebView", builder.toString());
}
}
return true;
}
});
}
特点
- 优点:不存在方式1的漏洞
- 缺点:JS获取Android方法的返回值复杂
如果JS想得到返回值,只能通过WebView的loadUrl()或evaluateJavascript()去执行JS 方法把返回值传递回去,相关的代码如下:
mWebView.loadUrl("javascript:callbackValue('dkjkdj')");
mWebView.evaluateJavascript("javascript:callbackValue('dkjkdj')", null);
2.3通过 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt() 消息
-
原理:Android通过 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调分别拦截JS对话框
(即上述三个方法),得到他们的消息内容,然后解析即可 -
实例:拦截js中prompt()方法
js中的代码:
function chromeClient(){
var result = prompt("demo://webview?arg1=1&arg2=2", "");
alert(result);
}
<button type="button" id="button3" onclick="chromeClient()">chromeClient</button>
Android 中通过WebChromeClient中onJsPrompt()方法拦截
public void onWebChromeClient(){
mWebView.setWebChromeClient(new WebChromeClient(){
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
return super.onJsAlert(view, url, message, result);
}
@Override
public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
return super.onJsConfirm(view, url, message, result);
}
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
Log.d("WebView", "url = "+ url + "message = " +message);
return super.onJsPrompt(view, url, message, defaultValue, result);
}
});
}
代码:
https://github.com/1411385476/WebViewDemo
参考资料:
WebView相关类的源码注释
https://mp.weixin.qq.com/s/0vVe-vh_OFW1nbWIv6o_4g
https://www.jianshu.com/p/b9164500d3fb
https://www.jianshu.com/p/3c94ae673e2a
最后
以上就是痴情钥匙为你收集整理的Web与JS交互的全部内容,希望文章能够帮你解决Web与JS交互所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复