android中JsBrage的使用

前言:项目中经常用到h5和原生交互的情形, 在这里介绍一个非常好用的第三方库JsBrage,先附上GitHub链接:https://github.com/lzyzsd/JsBridge

与JS交互有两种方式:

1、h5调用我们原生代码,然后原生可以给他反馈

2、原生调h5代码,然后h5处理完之后给原生反馈。

一、引用

在项目的build.gradle里(这个之前讲过,直接引用GitHub上的项目要指定它)

repositories {
    // ...
    maven { url "https://jitpack.io" }
}

在app的build.gradle里

dependencies {
    compile 'com.github.lzyzsd:jsbridge:1.0.4'
}

二、交互实例

1、demo中的布局文件

<?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"
    tools:context="library.mobilewcs.iscs.com.activity.custom_widget.jsbrage.JsBrageActivity"
    android:orientation="vertical">
    <Button
        android:id="@+id/default_bt"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="给js发送数据并获取反馈结果"
        android:textColor="#000"
        android:textSize="@dimen/common_dimen_dp20"
        android:gravity="center"
        android:layout_margin="@dimen/common_dimen_dp20"
        />

    <Button
        android:id="@+id/special_bt"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="给js指定方法发送数据并获取反馈结果"
        android:textColor="#000"
        android:textSize="@dimen/common_dimen_dp20"
        android:gravity="center"
        android:layout_margin="@dimen/common_dimen_dp20"
        />

    <com.github.lzyzsd.jsbridge.BridgeWebView
        android:id="@+id/webview"
        android:layout_width="match_parent"
        android:layout_height="@dimen/common_dimen_dp300" />
</LinearLayout>

上面的布局中有两个按钮,一个BridgeWebView(注意这里要用第三方的,不能用原生的WebView),第一个按钮是通过默认方式给js发送数据,并获取反馈结果, 第二个按钮是给js指定的方法发送数据并获取反馈结果。

2、demo中的html例子:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <script>
       <!--注册事件监听,初始化-->
       function setupWebViewJavascriptBridge(callback) {
           if (window.WebViewJavascriptBridge) {
               callback(WebViewJavascriptBridge)
           } else {
               document.addEventListener(
                   'WebViewJavascriptBridgeReady'
                   , function() {
                       callback(WebViewJavascriptBridge)
                   },
                   false
               );
           }
       }

       <!--回调函数,接收java发送来的数据-->
       setupWebViewJavascriptBridge(function(bridge) {
           //默认接收
           bridge.init(function(message, responseCallback) {
               document.getElementById("show").innerHTML = '默认接收到Java的数据: ' + message;

               var responseData = 'js默认接收完毕,并回传数据给java';
               responseCallback(responseData); //回传数据给java
           });

           <!--指定接收,参数functionInJs 与java保持一致-->
           bridge.registerHandler("functionInJs", function(data, responseCallback) {
               document.getElementById("show").innerHTML = '指定接收到Java的数据: ' + data;
               var responseData = 'js指定接收完毕,并回传数据给java';
               responseCallback(responseData);  <!--回传数据给java-->
           });
       })

       <!--js传递数据给java-->
       function jsCallJavaDefault() {
           var data = '发送数据给java默认接收';
           window.WebViewJavascriptBridge.send(data, function(responseData) {
                  document.getElementById("show").innerHTML = responseData;
           });
        }

       function jsCallJavaSpec() {
           var data='发送数据给java指定接收';
           <!--指定接收参数 submitFromWeb与java一致, function(responseData)处理java回传的数据-->
           window.WebViewJavascriptBridge.callHandler('callFromWeb',data,function(responseData) {
                  document.getElementById("show").innerHTML = responseData;
           });
       }
    </script>

</head>
<body>
<div>
    <button onClick="jsCallJavaDefault()">js调用java,Java使用默认方式接收</button>
</div>
<br/>
<div>
    <button onClick="jsCallJavaSpec()">js发送数据给java指定其某个方法接收</button>
</div>
<br/>
<div id="show">打印信息</div>
</body>
</html>

html中也有两个按钮,第一个是用默认方式给原生发送数据并获取反馈结果,第二个按钮是发送数据给原生指定的方法,并获取反馈数据, 最上面的js是初始化的,setupWebViewJavascriptBridge是注册接收数据的方法,里面有两个方法,第一个是默认接收,第二个原生可以通过functionInJs这个字符串调用到这个函数, 也可以根据业务添加更多这样的函数,原生可以通过第一个字符串调用到。最后两个方法jsCallJavaDefault()和jsCallJavaSpec()是两个html按钮的点击事件, 当用户点击第一个按钮的时候回通过默认的方式给原生发消息,点击第二个按钮的时候会调用前端以"callFromWeb"这个字符串注册的函数

3、原生代码

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.github.lzyzsd.jsbridge.BridgeHandler;
import com.github.lzyzsd.jsbridge.BridgeWebView;
import com.github.lzyzsd.jsbridge.CallBackFunction;

import library.mobilewcs.iscs.com.libraryproject.R;

public class JsBrageActivity extends Activity {

    Button defaultBt;
    Button specBt;
    BridgeWebView mWebView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_js_brage);

        defaultBt = findViewById(R.id.default_bt);
        specBt = findViewById(R.id.special_bt);
        mWebView = findViewById(R.id.webview);

        OnButtonClick onButtonClick = new OnButtonClick();
        defaultBt.setOnClickListener(onButtonClick);
        specBt.setOnClickListener(onButtonClick);

        // 加载Assert下的HTML文件
        mWebView.loadUrl("file:android_asset/test.html");

        // 注册js可以调用的方法, 一种是默认接收,一种是通过第一个参数指定接收
        //默认接收
        mWebView.setDefaultHandler(new BridgeHandler() {
            @Override
            public void handler(String data, CallBackFunction function) {
                String msg = "默认接收到js的数据:" + data;
                Toast.makeText(JsBrageActivity.this, msg, Toast.LENGTH_LONG).show();

                function.onCallBack("java默认接收数据,并回传数据给js"); //回传数据给js
            }
        });
        //指定接收 submitFromWeb 与js保持一致
        mWebView.registerHandler("callFromWeb", new BridgeHandler() {
            @Override
            public void handler(String data, CallBackFunction function) {
                String msg = "指定接收到js的数据:" + data;
                Toast.makeText(JsBrageActivity.this, msg, Toast.LENGTH_LONG).show();

                function.onCallBack("java指定接收数据,并回传数据给js"); //回传数据给js
            }
        });
    }

    class OnButtonClick implements View.OnClickListener {
        @Override
        public void onClick(View view) {
            if (view == defaultBt) {
                // 给js以默认的方式传数据,并获取返回值
                //默认接收
                mWebView.send("java发送数据给js数据, 对方使用默认接收", new CallBackFunction() {
                    @Override
                    public void onCallBack(String data) { //处理js回传的数据
                        Toast.makeText(JsBrageActivity.this, data, Toast.LENGTH_LONG).show();
                    }
                });
            }
            else if (view == specBt) {
                // js注册了functionInJs, 然后Java指定它来接收这个数据
                mWebView.callHandler("functionInJs", "发送数据给js指定接收", new CallBackFunction() {
                    @Override
                    public void onCallBack(String data) { //处理js回传的数据
                        Toast.makeText(JsBrageActivity.this, data, Toast.LENGTH_LONG).show();
                    }
                });
            }
        }
    }
}

这个是原生代码,进来加载webview,然后在onCreate里面注册了两个接收函数,第一个是默认接收,第二个是“callFromWeb”注册的,js可以根据这个字符串调用到这个方法。

点击原生的第一个按钮,调用mWebView.send()默认方式给js发送数据,通过回调onCallBack()来获取反馈结果。

点击第二个按钮调用mWebView.callHandler()来给js注册的"functionInJs"这个函数发送数据,并且通过onCallBack()获取返回结果。

三、替换成X5内核

JSBridge使用的是默认的webkit,如何换成X5WebView内核呢?

1、首先下载X5WebView的库,https://x5.tencent.com/tbs/sdk.html

2、直接复制库里面的jar包和so文件,放到自己的工程中, 然后复制Application里的初始化代码到自己的Application中,最后build.gradle里配置:

ndk {
    abiFilters "armeabi"
}

最后运行看看Application里的初始化回调返回true表示成功,如果为false就初始化失败了,然后会自动切换到系统默认浏览器内核

3、下载JSBridge源码被主工程依赖,这里是重点,要把刚才的X5的jar和so库复制到JSBridge库里, ndk配置也在JSBridge的build.gradle里,否则引用不到。

4、把下面红框里的文件中的引用包的地方,都替换成x5库里的包:

通过以上步骤即可把JSBridge的内核替换成X5的内核

采坑注意:

1、对WebView设置的时候,依然要引用android.webkit.WebSettings

2、监听网页加载完成要继承BridgeWebViewClient,并且监听到完成后要延时500毫秒,不然有可能调不到后端方法,这个坑踩得好辛苦!!

mWebView.setWebViewClient(new MyWebViewClient(mWebView));
public class MyWebViewClient extends BridgeWebViewClient {

        public MyWebViewClient(BridgeWebView webView) {
            super(webView);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    javaCallJs();
                }
            }, 500);

            LogUtils.showLog("onPageFish()");
        }

        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            super.onReceivedError(view, errorCode, description, failingUrl);
            LogUtils.showLog("onReceivedError()");
        }
    }

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值