介绍
代码
交互方式
js调用Android方法
- 通过WebView的addJavascriptInterface()进行对象映射
- 通过 WebViewClient 的shouldOverrideUrlLoading ()方法回调拦截 url
- 通过 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt()消息
本文只介绍addJavascriptInterface()的方法,实现方式最简单。
addJavascriptInterface()
public class AndroidFunction {
private Context context;
public AndroidFunction(Context context) {
this.context = context;
}
@JavascriptInterface
//将显示Toast和对话框的方法暴露给JS脚本调用
public String showToast(String name) {
Toast.makeText(context, name, Toast.LENGTH_SHORT).show();
return "这是Android的返回值,可供js获取";
}
}
webView.getSettings().setJavaScriptEnabled(true); //设置WebView属性,运行执行js脚本
//将object对象暴露给Js,调用addjavascriptInterface
webView.addJavascriptInterface(new AndroidFunction(WebViewActivity.this), "androidFunction");
showToast(str) {
let android_data =window.androidFunction.showToast(str);//调用Android的toast方法
console.log(android_data) //打印Android方法的返回值
},
<el-button @click="showToast('测试JS调用Android的toast方法!')">调用Android方法</el-button>
Android调用js方法
对于Android调用JS代码的方法有2种:
- 通过WebView的loadUrl()
- 通过WebView的evaluateJavascript()
两者方法的区别:
- loadUrl() 会刷新页面,evaluateJavascript() 则不会使页面刷新,所以 evaluateJavascript() 的效率更高
- loadUrl() 得不到 js 的返回值,evaluateJavascript() 可以获取返回值
- evaluateJavascript() 在 Android 4.4 之后才可以使用
Android调用js方式 | 优点 | 缺点 | 使用场景 |
---|---|---|---|
loadUrl() | 方便简洁 | 效率低;获取返回值麻烦 | 不需要获取返回值,对性能要求比较低 |
evaluateJavascript() | 效率高 | 向下兼容性差(仅Android 4.4以上可用) | Android 4.4以上 |
loadUrl()和evaluateJavascript()
<template>
<el-row>
<p id="p" style="word-wrap:break-word;word-break:break-all;">Android调用js方法的输出:</p>
</el-row>
</template>
<script>
export default {
data() {
return{}
},
methods: {
jsfunction(str) {
document.getElementById("p").innerHTML += str;
let json_data = {
test:1,
test2:"这是js的返回值,可供Android获取"
}
return json_data //Android调用js方法,可获取返回值
},
},
created() {
window.jsfunction = this.jsfunction;
},
};
</script>
webView.loadUrl("javascript:jsfunction('loadUrl方法传参;')");
webView.evaluateJavascript("javascript:jsfunction('evaluateJavascript方法传参;')", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
//打印js方法返回值
System.out.println("js方法返回的结果: " +s);
Toast.makeText(WebViewActivity.this, s, Toast.LENGTH_SHORT).show();
}
});
Android代码汇总
public class WebViewActivity extends AppCompatActivity {
private WebView webView;
private Button btn_callJsFunction;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.webview_layout);
webView = findViewById(R.id.wView);
btn_callJsFunction = findViewById(R.id.button_callJsFunction);
webView.setWebViewClient(new WebViewClient() {
//设置在webView点击打开的新网页在当前界面显示,而不跳转到新的浏览器中
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
webView.getSettings().setJavaScriptEnabled(true);//是否允许执行js,默认为false。设置true时,会提醒可能造成XSS漏洞
//将object对象暴露给Js,调用addjavascriptInterface
webView.addJavascriptInterface(new AndroidFunction(WebViewActivity.this), "androidFunction");
//vue的链接页面网址
webView.loadUrl("http://192.168.0.105:8089/csdntest");
//调用js方法的按钮点击事件
btn_callJsFunction.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
webView.loadUrl("javascript:jsfunction('loadUrl方法传参;')");
// callJsFunction();
webView.evaluateJavascript("javascript:jsfunction('evaluateJavascript方法传参;')", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
//打印js方法返回值
System.out.println("js方法返回的结果: " +s);
Toast.makeText(WebViewActivity.this, s, Toast.LENGTH_SHORT).show();
}
});
}
});
}
}
public class AndroidFunction {
private Context context;
public AndroidFunction(Context context) {
this.context = context;
}
@JavascriptInterface
//将显示Toast和对话框的方法暴露给JS脚本调用
public String showToast(String name) {
Toast.makeText(context, name, Toast.LENGTH_SHORT).show();
return "这是Android的返回值,可供js获取";
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="48dp">
<Button
android:id="@+id/button_callJsFunction"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:text="调用js方法" />
</RelativeLayout>
<WebView
android:id="@+id/wView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</WebView>
</LinearLayout>
vue代码汇总
<template>
<el-row>
<p id="p" style="word-wrap:break-word;word-break:break-all;">Android调用js方法的输出:</p>
<el-button @click="showToast('测试JS调用Android的toast方法!')">调用Android方法</el-button>
<div style = "height:1000px"></div>
</el-row>
</template>
<script>
export default {
data() {
return{}
},
methods: {
showToast(str) {
let android_data =window.androidFunction.showToast(str);//调用Android的toast方法
console.log(android_data) //打印Android方法的返回值
},
jsfunction(str) {
document.getElementById("p").innerHTML += str;
let json_data = {
test:1,
test2:"这是js的返回值,可供Android获取"
}
return json_data //Android调用js方法,可获取返回值
},
},
created() {
window.jsfunction = this.jsfunction;
},
};
</script>
本文参考
菜鸟教程:WebView和JavaScrip交互基础
Carson带你学Android:全面总结WebView与 JS 的交互方式
安卓webview原生和JavaScript(js)交互传值的4种方式 java和js交互 安卓JsBridge原理解析