Android开发过程中我们或多或少都会用到WebView,使用WebView来展示一些需要经常变动的界面,也易于维护。同时另一方面hybrid App开发现在用的也越来越多了。其中native和h5之间的交互更是必不可少的。具体Android中是如何和h5交互的?或者说Android中是如何和js交互的。
使用WebView加载网页
webView.loadUrl("https://www.baidu.com");
但是大多数情况下可没这么简单,比如网页内部链接的跳转、返回键的处理、特定地址的处理、加载进度和进度条的处理;下面是一个简单的示例
public class JSActivity extends BaseActivity {
WebView webView;
ProgressDialog progressDialog;
@Override
public int getLayoutId() {
return R.layout.ac_js;
}
@Override
public void initData() {
super.initData();
webView = getView(R.id.web_view);
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//我们可以在这里拦截特定的rl请求,然后进行自己要的操作
if (url.equals("file:///android_asset/test2.html")) {
Log.e(TAG, "shouldOverrideUrlLoading: " + url);
return true;
} else {
//这里我们自己重新加载新的url页面,防止点击链接跳转到系统浏览器
webView.loadUrl(url);
return true;
}
}
/**
* 界面打开的回调
*/
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
//弹出菊花
progressDialog = new ProgressDialog(JSActivity.this);
progressDialog.setTitle("提示");
progressDialog.setMessage("软软正在拼命加载……");
progressDialog.show();
}
/**
* 界面打开完毕的回调
*/
@Override
public void onPageFinished(WebView view, String url) {
//隐藏菊花:不为空,正在显示。才隐藏关闭
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
});
webView.setWebChromeClient(new WebChromeClient() {
/**
* 进度改变的回调
* WebView:就是本身
* newProgress:即将要显示的进度
*/
@Override
public void onProgressChanged(WebView view, int newProgress) {
if (progressDialog != null && progressDialog.isShowing())
progressDialog.setMessage("软软正在拼命加载……" + newProgress + "%");
}
});
}
@Override
public void action() {
super.action();
webView.loadUrl("https://www.baidu.com");
}
@Override
public void onBackPressed() {
if (webView.canGoBack()) {
//返回上一个页
webView.goBack();
return;
}
super.onBackPressed();
}
}
上面只是简单的html展示,但实际开发中我们需要与html进行交互;Native调用JS,JS调用Native,
- java调用js分两种情况:有返回值和无返回值
无返回值时直接
webView.loadUrl("javascript:showInfoFromJava()");
showInfoFromJava()是js方法
有返回值时需要使用mWebView.evaluateJavascript()方法
webView.evaluateJavascript("sum(1,2)", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
tvShow.setText("调用sun(1,2)的返回值是: " + value);
}
});
- js调用java方法
在android 4.2以上可以直接使用@javascriptinterface注解来声明,下面是在一个本地java方法
public void addJavascriptInterface(Object object, String name);
object参数:在object对象里面添加我们想要在Js里面调用的Android方法;name可以理解为实例 。在js中的调用就是 实例.方法名 ;
java代码
webView.addJavascriptInterface(new Object() {
//定义要调用的方法
//msg由js调用的时候传递
@JavascriptInterface
public void showToast(String msg) {
Toast.makeText(getApplicationContext(),
msg, Toast.LENGTH_SHORT).show();
}
}, "JSTest");
js代码
function showToast(){
JSTest.showToast("我是被JS执行的Android代码");
}
在下面贴出的实例代码中,还有一种在同一实例中定义多个方法的方式。
JS2Activity.class
public class JS2Activity extends BaseActivity {
WebView webView;
Button b1, b2;
TextView tvShow;
@Override
public int getLayoutId() {
return R.layout.ac_js2;
}
@Override
public void initData() {
super.initData();
webView = getView(R.id.web_view);
b1 = getView(R.id.bt_o);
b2 = getView(R.id.bt_t);
tvShow = getView(R.id.show_data);
//首先设置Webview支持JS代码
webView.getSettings().setJavaScriptEnabled(true);
b1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// webView.loadUrl("javascript:showInfoFromJava('Native传递给JS的信息')");
webView.loadUrl("javascript:showInfoFromJava()");
}
});
b2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
webView.evaluateJavascript("sum(1,2)", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
tvShow.setText("调用sun(1,2)的返回值是: " + value);
}
});
}
});
webView.addJavascriptInterface(new Object() {
//定义要调用的方法
//msg由js调用的时候传递
@JavascriptInterface
public void showToast(String msg) {
Toast.makeText(getApplicationContext(),
msg, Toast.LENGTH_SHORT).show();
}
}, "JSTest");
webView.addJavascriptInterface(new JsInterface(this), "JsInterface");
}
@Override
public void action() {
super.action();
webView.loadUrl("file:///android_asset/test.html");
}
@SuppressLint({"SetJavaScriptEnabled", "AddJavascriptInterface"})
class JsInterface {
private Context mContext;
public JsInterface(Context context) {
this.mContext = context;
}
@JavascriptInterface
public String getName() {
return TAG;
}
@JavascriptInterface
public String getPass() {
return getPass();
}
}
}
test.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
<script>
function sum(a,b){
return a+b;
}
function showInfoFromJava(){
document.getElementById("demo").innerHTML="Java成功调的JS方法";
}
function showToast(){
JSTest.showToast("我是被JS执行的Android代码");
}
function getName(){
var name=JsInterface.getName();
document.getElementById("demo").innerHTML="JS调用Native方法的返回值: "+name;
}
</script>
</head>
<body>
<h1>我的第一个 JavaScript 程序</h1>
<p id="demo">这是一个段落</p>
<button type="button" onclick="showToast()">JS调用Native无返回值函数</button>
<button type="button" onclick="getName()">JS调用Native有返回值函数</button>
</body>
</html>
网友评论