文章目录
Hybrid开发—WebView与js交互实现
一、 引言
Hybrid App(混合模式移动应用)是指介于web-app、native-app这两者之间的app,兼具“Native App良好交互体验的优势”和“Web App跨平台开发的优势”。
当前Hybrid技术也分了几个门派,其中主流的两派——
- 一派是采用ReactNative或者weex之类的框架来实现,通俗点说就是程序员用js写代码,然后框架负责把js代码翻译成原生代码,最后呈现出原生页面;
- 另外一派是采用WebView组件,程序员写的是纯粹的h5代码,最后也是通过原生端的WebView组件来加载渲染,和WebApp的区别就是,WebApp整个app是一个web容器,各种页面跳转包括效果实现都是在这个容器中通过H5技术实现。
而Hybrid-WebView的实现方案中,每个页面都是一个独立的WebView容器,页面之间的跳转,一些特殊效果,特殊组件的实现,都是通过H5发消息来调取原生功能实现的。
二、WebView与js交互
一、WebView
WebView组件是Android提供用于显示网页信息,它内置了WebKit引擎,WebKit是一个开源的浏览器引擎,Chrome浏览器也是基于它,所以我们可以把WebView当做一个轻量级的浏览器使用。如果对WebView的使用以及方法不是很了解,可以看Android:这是一份全面 & 详细的Webview使用攻略这篇文章,这里面讲解了WebView 的基本使用。
二、交互小Demo
下面我们进入正题,WebView 是如何与JS 进行交互的。请看下面这个图片:
蓝色的部分是WebView控件,加载的是本地的一个HTML 网页。黄色的是app 本身的布局,在输入框中输入数据然后点击发送,就能把数据发送给Js进行处理,在网页中点击发送按钮,也同样的能把网页中输入框内的数据发送给app 本身并显示出来,这个小Demo 就简单的实现了WebView与js 整个的交互过程。下面看整个交互过程图:
OK ,下面我们来实现这个小Demo。
三、具体实现
1、首先是界面xml 布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.sxl.webviewdemo.MainActivity">
<!--显示网页区域-->
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="300dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#F8DC26">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这里是Native"
android:textSize="20sp" />
<TextView
android:id="@+id/tv_Data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:text="从HTML返回的数据"
android:textSize="20sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:orientation="horizontal">
<EditText
android:id="@+id/edtTxt_Data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:layout_weight="1"
android:gravity="center"
android:hint="输入的数据将在HTML中显示" />
<Button
android:id="@+id/btn_Send"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginRight="20dp"
android:text="发送" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
2、初始化webView控件
mWebview = (WebView) findViewById(R.id.webView);
// 获取mWebSettings 对WebView进行配置和管理
mWebSettings = mWebview.getSettings();
// 允许webview 加载js代码
mWebSettings.setJavaScriptEnabled(true);
// 加载本地html
mWebview.loadUrl("file:///android_asset/WebViewDemo.html");
//设置不用系统浏览器打开,直接显示在当前Webview
mWebview.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
//设置WebChromeClient类
mWebview.setWebChromeClient(new WebChromeClient() {
//获取网站标题
@Override
public void onReceivedTitle(WebView view, String title) {
getSupportActionBar().setTitle(title);
}
});
3、创建WebViewDemo.html文件
创建WebViewDemo.html文件,并将这个HTML文件放入到main 文件夹下的assets 文件夹内,如果没人assets 这个文件吗,则创建。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebView小Demo</title>
<style type="text/css">
body{
background: #61aaff;
}
</style>
</head>
<body>
<h2>这里是HTML网页</h2>
<div><span>要输入的数据:</span><input type="text" id="input"></div><br>
<button id="button">发送给Android</button>
</body>
</html>
4、Android通过WebView的 loadUrl方法调用 JS 代码
首先在WebViewDemo.html 创建 js 方法
<script type="text/javascript">
var data=document.getElementById("input");
// 定义js 方法,会被 Android 调用
var send=function(str) {
data.value=str;
}
</script>
在Android中调用js 方法
btnSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String str = edtTxtData.getText().toString();
// 调用js 中的send 方法并传参
mWebview.loadUrl("javascript:if(window.send){window.send('" + str + "')}");
}
});
5、JS通过WebView 的addJavascriptInterface 方法调用 Android 代码(4.2及以上的系统才能使用)
首先定义一个 JSInterface.java 接口文件,定义 setVaule 方法。
public interface JSInterface {
void setVaule(String vaule);
}
然后 JStoAndroid 类中实现这个方法。
public class JStoAndroid {
private JSInterface jsInterface;
public JStoAndroid(JSInterface jsInterface){
this.jsInterface=jsInterface;
}
/**
* 定义JS需要调用的方法
* 被JS调用的方法必须加入@JavascriptInterface注解
* 这种方式只能在Android 4.2及以上的系统才能使用
*/
@JavascriptInterface
public void setValue(String vaule) {
jsInterface.setVaule(vaule);
}
}
下面在主界面中 加载 js 接口:
// 给webView 加载js 接口
mWebview.addJavascriptInterface(new JStoAndroid(new JSInterface() {
@Override
public void setVaule(final String vaule) {
// 将在js 接口中获取到的数据 通过handler 传到主线程更新界面
handler.post(new Runnable() {
@Override
public void run() {
tvData.setText(vaule);
}
});
}
}), "sendData"); // "sendData" 对应 js中 调用的方法名
最后添加 html 中按钮点击的 js 方法。
<script type="text/javascript">
var btn=document.getElementById("button");
var data=document.getElementById("input");
// 调用Android 中的方法
btn.addEventListener("click",function () {
var str=data.value;
// 判断 Android 加载js 接口的时候有没有定义的sendData 方法
if( window.sendData ){
sendData.setValue(str);
}else{
alert("Android 中没有对应的方法");
}
});
</script>
总结:
对于Android调用JS代码的方法有2种:
- 通过
WebView
的loadUrl()
- 通过
WebView
的evaluateJavascript()
对于JS调用Android代码的方法有3种:
- 通过
WebView
的addJavascriptInterface()
进行对象映射 - 通过
WebViewClient
的shouldOverrideUrlLoading ()
方法回调拦截 url - 通过
WebChromeClient
的onJsAlert()
、onJsConfirm()
、onJsPrompt()
方法回调拦截JS对话框alert()
、confirm()
、prompt()
消息
以上就是对Android与js 直接交互实现的小Demo 的讲解,具体代码已经上传到github,点击 WebViewDemo 即可查看。