介绍
本文将实现HTML - JS - Java来完成HTML5端与Android手机间的互访!并实现方法的传参和返回值的获取。
代码
交互方式
js调用Android方法
- 通过WebView的addJavascriptInterface()进行对象映射;
- 通过 WebViewClient 的shouldOverrideUrlLoading ()方法回调拦截 url;
- 通过 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt()消息;
本文只介绍addJavascriptInterface()的方法,实现方式最简单。
实现效果
展示js调用Android方法的传参和返回值获取; 点击h5的“调用Android方法”按钮,h5传参给Android的toast方法,Android显示toast提示并传回返回值给前端。
toast提示
|
获取到Android返回值
|
addJavascriptInterface()
编写一个AndroidFunction.class文件提供Android方法,如toast的方法。其中也可设置返回值给前端。 @JavascriptInterface的作用:Google 在Android 4.2 版本中规定对被调用的函数以 @JavascriptInterface进行注解从而避免漏洞攻击。
public class AndroidFunction {
private Context context;
public AndroidFunction(Context context) {
this.context = context;
}
@JavascriptInterface
public String showToast(String name) {
Toast.makeText(context, name, Toast.LENGTH_SHORT).show();
return "这是Android的返回值,可供js获取";
}
}
对应的activity文件设置暴露Android方法。
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new AndroidFunction(WebViewActivity.this), "androidFunction");
前端可通过window.androidObject.androidMethod()的方式获取Android方法。并可传值,也可获取Android方法的返回值。
showToast(str) {
let android_data =window.androidFunction.showToast(str);
console.log(android_data)
},
前端的点击按钮,实现调用js方法。
<el-button @click="showToast('测试JS调用Android的toast方法!')">调用Android方法</el-button>
Android调用js方法
对于Android调用JS代码的方法有2种:
- 通过WebView的loadUrl();
- 通过WebView的evaluateJavascript();
两者方法的区别:
Android调用js方式 | 优点 | 缺点 | 使用场景 |
---|
loadUrl() | 方便简洁 | 效率低;获取返回值麻烦 | 不需要获取返回值,对性能要求比较低 | evaluateJavascript() | 效率高 | 向下兼容性差(仅Android 4.4以上可用) | Android 4.4以上 |
实现效果
展示Android调用js方法的传参和返回值获取; 点击原生的的“调用Js方法”按钮,loadUrl()和evaluateJavascript()分别调用js方法并传参,输出h5的p标签上;js方法返回值会显示在toast提示上和Android输出框中捕获到。
调用js方法
|
打印js方法的返回值
|
loadUrl()和evaluateJavascript()
vue暴露js方法给window对象,Android才能访问;Android调用后会在p标签上添加传参的文本。
<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
},
},
created() {
window.jsfunction = this.jsfunction;
},
};
</script>
Android调用通过loadUrl()和evaluateJavascript()调用js方法。evaluateJavascript()则可获取js方法的返回值。
webView.loadUrl("javascript:jsfunction('loadUrl方法传参;')");
webView.evaluateJavascript("javascript:jsfunction('evaluateJavascript方法传参;')", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
System.out.println("js方法返回的结果: " +s);
Toast.makeText(WebViewActivity.this, s, Toast.LENGTH_SHORT).show();
}
});
Android代码汇总
WebViewActivity
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() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new AndroidFunction(WebViewActivity.this), "androidFunction");
webView.loadUrl("http://192.168.0.105:8089/csdntest");
btn_callJsFunction.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
webView.loadUrl("javascript:jsfunction('loadUrl方法传参;')");
webView.evaluateJavascript("javascript:jsfunction('evaluateJavascript方法传参;')", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
System.out.println("js方法返回的结果: " +s);
Toast.makeText(WebViewActivity.this, s, Toast.LENGTH_SHORT).show();
}
});
}
});
}
}
AndroidFunction
public class AndroidFunction {
private Context context;
public AndroidFunction(Context context) {
this.context = context;
}
@JavascriptInterface
public String showToast(String name) {
Toast.makeText(context, name, Toast.LENGTH_SHORT).show();
return "这是Android的返回值,可供js获取";
}
}
webview_layout.xml
<?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代码汇总
csdntest.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);
console.log(android_data)
},
jsfunction(str) {
document.getElementById("p").innerHTML += str;
let json_data = {
test:1,
test2:"这是js的返回值,可供Android获取"
}
return json_data
},
},
created() {
window.jsfunction = this.jsfunction;
},
};
</script>
本文参考
菜鸟教程:WebView和JavaScrip交互基础 Carson带你学Android:全面总结WebView与 JS 的交互方式 安卓webview原生和JavaScript(js)交互传值的4种方式 java和js交互 安卓JsBridge原理解析
|