JS与Android互调
现在很多原生的APP中都会或多或少的嵌入一些H5页面,这就需要学习一下原生APP与H5页面中的数据是如何做交互的。废话不多少,直接上干货。
1. 如何使用?
其实Android和JS之间互相调用非常简单,首先使用WebView将H5页面加载出来,当需要java代码调用js代码时: WebView.loadUrl(“javaScript:js方法名称()”) ; 当js代码调用java代码时:就需要有一个js与java链接桥对象,然后在js代码中使用:window.jsObj.java方法() , 其中jsObj是js与java桥链接对象的别名。是不是使用起来很简单啊,但是在调用之前还需要对WebView进行配置。
WebView.setWebChromeClient(); // 该方法主要处理解析,渲染等浏览器做的事情,WebChromeClient用来辅助WebView处理JavaScript的对话框,网站图标,加载进度等,如果需要给WebView添加进度条可以复写里面的onProgressChanged()方法
WebView.getSettings().setJavaScriptEnabled(); // 如果需要启用javascript脚本,就需要设置为true,
WebView.setWebViewClient(); // 该方法帮助WebView处理各种通知,请求事件,为了让WebView中的所有跳转都在本App中,就需要设置该方法,
WebView.addJavaScriptInterface(new JSAndroidBridge(),"jsObj"); // 当需要js代码调用java代码的时候就需要传入一个对象,并给该对象起一个别名,在js代码中通过该别名来调用java代码中的方法,但是注意当targetSdkVersion值为17+时,js只能访问带有@JavascriptInterface注解的函数
2. 代码示例
//先贴Activity中的代码
public class MainActivity extends Activity implements View.OnClickListener {
private ProgressBar progress ;
private WebView webView ;
private String baidu = "http://www.baidu.com/" ; // 点击百度图片的时候,实现跳转到新的Activity中去
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView(){
findViewById(R.id.btn1).setOnClickListener(this);
findViewById(R.id.btn2).setOnClickListener(this);
progress = (ProgressBar) findViewById(R.id.progress);
webView = (WebView) findViewById(R.id.webView);
webView.setWebChromeClient(webChromeClient);// 设置WebChromeClient,监听加载进度,处理弹出事件等
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true); // 开启JavaScript脚本
webSettings.setDefaultTextEncodingName("utf-8"); // 设置默认编码
webView.addJavascriptInterface(new JSAndroidBridge() , "jsObj"); // 添加js与java链接的桥对象,并起别名为jsObj,在js中通过该别名调用
webView.setWebViewClient(webViewClient); // 设置该方法可以实现在APP中进行跳转,获取跳转链接等,本例子中就监听加载的url,来实现像原声APP跳转
webView.loadUrl("file:///android_asset/index.html"); // 从assets中加载网页
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()){ // 判断webview是否可返回,如果能返回,就返回到之前浏览的网页中
webView.goBack();
return true ;
}
return super.onKeyDown(keyCode, event);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn1 :
runOnUiThread(new Runnable() { // 这里调用了js来弹窗,是跟新UI的操作,所以必须要放到主线程中
@Override
public void run() {
webView.loadUrl("javaScript:js4AndroidNoParams()");
}
});
break;
case R.id.btn2 :
runOnUiThread(new Runnable() {
@Override
public void run() {
webView.loadUrl("javaScript:js4AndroidWithParams(2,3)");
}
});
break;
}
}
public class JSAndroidBridge{
@JavascriptInterface // 如果targetSdkVersion >= 17的时候必须要在被js调用的方法上添加在注解,
public String android4JsWithNoParams(){
return "js调用android无参方法";
}
@JavascriptInterface
public String android4JsWithParams(int x , int y){
return "js调用android含参方法返回的结果:" + ( x + y );
}
}
//复写添加加载进度监听
private WebChromeClient webChromeClient = new WebChromeClient(){
@Override
public void onProgressChanged(WebView view, int newProgress) {
progress.setProgress(newProgress);
if(newProgress == 100){
progress.setVisibility(View.GONE);
}
}
};
//拦截加载url,实现想原生APP跳转
private WebViewClient webViewClient = new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if(TextUtils.equals(url ,baidu)){ // 判断当加载的链接是百度图片的时候,实现跳转功能
Intent intent = new Intent(MainActivity.this , NewActivity.class);
startActivity(intent);
return true ;
}else{
view.loadUrl(url);
return false ;
}
}
};
}
java代码就这么多了,布局文件也很简单,下来再看看html代码吧
//html代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>Js与Android互调</title>
<script type="text/javascript">
<!--JS调用Android无参方法 -->
function android4JsWithNoParams(){
var text = window.jsObj.android4JsWithNoParams(); // 调用java代码的时候通过桥对象就ok了,
alert(text);
}
<!--JS调用Android含参方法 -->
function android4JsWithParams(){
var text = window.jsObj.android4JsWithParams(2,3);
alert(text);
}
<!--android 调用JS无参方法-->
function js4AndroidNoParams(){
alert("android 调用JS无参方法");
}
<!--android 调用JS含参方法 -->
function js4AndroidWithParams(x,y){
alert(x +" x " + y + " = " + (x*y));
}
</script>
</head>
<body>
<input width="100%p" height="20%p" type="button" value="JS调用Android无参方法" onclick="android4JsWithNoParams()"/></br></br>
<input width="100%p" height="20%p" type="button" value="JS调用Android有参方法" onclick="android4JsWithParams()"/></br>
<a href="http://www.baidu.com"><img width="50%" height="50%" src="https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png"/></a></br></br>
<a href="http://gank.io/"><img width="50%" height="50%" src="https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png"/></a></br>
</body>
</html>
有没有觉的js与android之间相互调用原来这么简单的赶脚 ,详情可以下载demo运行