本文附带了一点H5和JS的内容,所以需要有基本的JS知识。
学习JS基本知识可以看菜鸟教程。
我自己也看过总结了一下知识点https://blog.csdn.net/qq_41872247/article/details/128901143
我会写一个简单的demo,且demo不需要联网全程本地操作,在文章末尾贴上所有代码。
页面上面放两个按钮和一个WebView,WebView只需要提供JavaScript的支持就行,不需要特意做什么。
public class MainActivity extends AppCompatActivity {
WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webview);
findViewById(R.id.btn1).setOnClickListener(view -> {
});
findViewById(R.id.btn2).setOnClickListener(view -> {
});
initWebView();
}
private void initWebView() {
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true); // 让网页支持JavaScript代码
webView.setWebChromeClient(new WebChromeClient()); // 让H5的alert功能生效
webView.loadUrl("file:///android_asset/test.html");
}
}
同时我们在项目的app/src/main中创建assets文件夹,把我们写的空页面放上去,准备就完成了。
<html>
<head>
<title>test.htmltitle>
<script>
script>
head>
<body>
<button onclick="">按钮1button>
<button onclick="">按钮2button>
body>
html>
H5需要和原生交互,首先要原生提供对应的支持接口,然后H5就可以通过这个接口访问客对应方法了,代码如下(刚才出现过的代码会省略):
public class MainActivity extends AppCompatActivity {
// ...省略无关代码
private void initWebView() {
// ...省略无关代码
MyInterface myInterface = new MyInterface(this);
// 通过这个API增加和H5的交互接口,每个WebView的实例都要调用才会添加,name参数决定了这个接口的名称
webView.addJavascriptInterface(myInterface, "interface1");
}
}
class MyInterface {
private final Context context;
public MyInterface(Context context) {
this.context = context;
}
/**
* 只要在对应的方法上加上JavaScriptInterface的标签,这个方法就会变成和H5的交互接口
*/
@JavascriptInterface
public void testFunction1() {
Toast.makeText(context, "我是原生测试方法", Toast.LENGTH_SHORT).show();
}
/**
* 方法可以自带入参和返回值
*/
@JavascriptInterface
public String testFunction2(String param) {
return param + ", helloworld";
}
}
<html>
<head>
<title>test.htmltitle>
<script>
function appTest1() {
// window是固定写法,interface1是App添加接口时写的具体名称,testFunction是具体的方法
window.interface1.testFunction1()
}
function appTest2() {
// 调用方法可以带入参,一般我们都用String,如果要传数据对象就把他json化
var t = window.interface1.testFunction2('woshiH5')
alert('我是带参数和返回值的测试方法:' + t)
}
script>
head>
<body>
<button onclick="appTest1()">按钮1button>
<button onclick="appTest2()">按钮2button>
body>
html>
原生调H5只需要像正常情况一样写H5的代码就行,代码如下:
public class MainActivity extends AppCompatActivity {
WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webview);
findViewById(R.id.btn1).setOnClickListener(view -> {
// 正常的调用网页中已声明的方法即可
// 同理,WebView可以自由的使用JS代码来操作网页,不仅是方法,实例和变量都能操作。
webView.evaluateJavascript("h5Test1()", null);
});
findViewById(R.id.btn2).setOnClickListener(view -> {
webView.evaluateJavascript("h5Test2()", new ValueCallback<String>() {
/**
* 返回值的类型只能是String,所以我们一般用JSON格式来传递数据
*/
@Override
public void onReceiveValue(String value) {
Toast.makeText(MainActivity.this, value, Toast.LENGTH_SHORT).show();
}
});
});
}
//...省略刚才出现过的代码
}
<html>
<head>
<title>test.htmltitle>
<script>
// ...省略无关代码
function h5Test1() {
alert('我是测试方法1,我被调用了!')
}
function h5Test2() {
var t = '我是测试方法2,我是个字符串'
return t
}
script>
head>
<body>
body>
html>
直接复制到空项目里面,解决import后就能运行
public class MainActivity extends AppCompatActivity {
WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webview);
findViewById(R.id.btn1).setOnClickListener(view -> {
webView.evaluateJavascript("h5Test1()", null);
});
findViewById(R.id.btn2).setOnClickListener(view -> {
webView.evaluateJavascript("h5Test2()", new ValueCallback<String>() {
/**
* 返回值的类型只能是String,所以我们一般用JSON格式来传递数据
*/
@Override
public void onReceiveValue(String value) {
Toast.makeText(MainActivity.this, value, Toast.LENGTH_SHORT).show();
}
});
});
initWebView();
}
private void initWebView() {
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setJavaScriptCanOpenWindowsAutomatically(true);
webView.setWebChromeClient(new WebChromeClient());
webView.loadUrl("file:///android_asset/test.html");
MyInterface myInterface = new MyInterface(this);
// 通过这个API增加和H5的交互接口,每个WebView的实例都要调用才会添加,name参数决定了这个接口的名称
webView.addJavascriptInterface(myInterface, "interface1");
}
}
class MyInterface {
private final Context context;
public MyInterface(Context context) {
this.context = context;
}
/**
* 只要在对应的方法上加上JavaScriptInterface的标签,这个方法就会变成和H5的交互接口
*/
@JavascriptInterface
public void testFunction1() {
Toast.makeText(context, "我是原生测试方法", Toast.LENGTH_SHORT).show();
}
/**
* 方法可以自带入参和返回值
*/
@JavascriptInterface
public String testFunction2(String param) {
return param + ", helloworld";
}
}
网页全代码,新建html文件之后用文本文档打开,复制进去即可。
<html>
<head>
<title>test.htmltitle>
<script>
function appTest1() {
// window是固定写法,interface1是App添加接口时写的具体名称,testFunction是具体的方法
window.interface1.testFunction1()
}
function appTest2() {
// 调用方法可以带入参,一般我们都用String,如果要传数据对象就把他json化
var t = window.interface1.testFunction2('woshiH5')
alert('我是带参数和返回值的测试方法:' + t)
}
function h5Test1() {
alert('我是测试方法1,我被调用了!')
}
function h5Test2() {
var t = '我是测试方法2,我是个字符串'
return t
}
script>
head>
<body>
<button onclick="appTest1()">按钮1button>
<button onclick="appTest2()">按钮2button>
body>
html>