Hybrid开发—WebView与js交互实现

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种:

  1. 通过WebViewloadUrl()
  2. 通过WebViewevaluateJavascript()

对于JS调用Android代码的方法有3种:

  1. 通过WebViewaddJavascriptInterface()进行对象映射
  2. 通过 WebViewClientshouldOverrideUrlLoading ()方法回调拦截 url
  3. 通过 WebChromeClientonJsAlert()onJsConfirm()onJsPrompt()方法回调拦截JS对话框alert()confirm()prompt() 消息

以上就是对Android与js 直接交互实现的小Demo 的讲解,具体代码已经上传到github,点击 WebViewDemo 即可查看。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值