天天看點

Android端使用lzyzsd/JsBridge筆記1.背景2.開發工具3.js_native_contact_demo

1.背景

之前隻是用webview展示網頁,和前端小夥伴沒怎麼聯調過,傳uid和token也是直接在連結後面拼,但實際複雜些項目中不可避免要和前端進行互相調用,今天重新看了一遍大佬寫的JsBridge,寫一個使用的小筆記

前排放入github傳送門,星星最多的jsbridge! 7.4k ,同時感謝大佬

lzyzsd/JsBridge

2.開發工具

AndroidStudio

3.js_native_contact_demo

1.建立一個android項目,正常操作~ (ps:項目能跑起來沒問題吧…)

Android端使用lzyzsd/JsBridge筆記1.背景2.開發工具3.js_native_contact_demo

2.建立一個assets檔案夾,如上圖所示,裡面建立一個叫demo.html的檔案,代碼直接貼進去,複制粘貼才是王道,手敲都是異類(不接受反駁,小聲xx~+邪笑.png)

<html xmlns:white-space="http://www.w3.org/1999/xhtml">
<head>
    <meta content="text/html; charset=utf-8" http-equiv="content-type">
    <!-- 網頁适配手機頁面-->
    <meta name="viewport"
          content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
    <title>
        js調用java
    </title>
</head>

<body bgcolor="#f0ffff">
<div>
    <p id="show" style="background-color:white">
    </p>
    <pre id="init">
    </pre>
    <p>
        <input type="text" id="text1" value="username"/>
    </p>
    <p>
        <input type="text" id="text2" value="address"/>
    </p>
    <p>
        <input type="button" id="enter" value="無需配置設定handle方法名(預設的),直接發消息給native"
               onclick="jsToNativeDefault();"
        />
    </p>
    <p>
        <input type="button" id="enter1" value="通過submitFromWeb的handle方法名,調用native的同名方法"
               onclick="jsToNativeCustom();"
        />
    </p>
    <p>
        <input type="button" id="enter2" value="顯示html" onclick="testDiv();"/>
    </p>
    <p>
        <input type="file" value="預設為type的input輸入框,手機上沒什麼反應,在pc端會自動打開選擇檔案的視窗,點選檔案會将檔案名輸入"/>
    </p>
    <xmp id='showHtml' style='background-color:white'/>
</div>
</body>
<script>


    // js發送native預設的消息
    function jsToNativeDefault() {
        var str1 = document.getElementById("text1").value;
        var str2 = document.getElementById("text2").value;

        //send message to native
        var data = {id: 1, content: "通過js頁面點選,調用預設方法,發送該資訊到手機端"};
        window.WebViewJavascriptBridge.send(
            data
            , function (responseData) {
                document.getElementById("show").innerHTML = "發消息給native,并收到了native的回報如下\n" + responseData
            }
        );

    }

    // js發送native自定義名字的消息
    function jsToNativeCustom() {
        var str1 = document.getElementById("text1").value;
        var str2 = document.getElementById("text2").value;

        //call native method
        window.WebViewJavascriptBridge.callHandler(
            'submitFromWeb'
            , {'param': '通過js頁面點選,調用submitFromWeb方法,發送該資訊到手機端'}
            , function (responseData) {
                document.getElementById("show").innerHTML = "發消息給native,并收到了native的回報如下\n" + responseData
            }
        );
    }

    // 将html标簽下的所有代碼貼入xmp标簽裡
    function testDiv() {
        document.getElementById("showHtml").innerHTML = document.getElementsByTagName("html")[0].innerHTML;
    }

    // 設定向native發送的回調
    function connectWebViewJavascriptBridge(callback) {
        if (window.WebViewJavascriptBridge) {
            callback(WebViewJavascriptBridge)
        } else {
            document.addEventListener(
                'WebViewJavascriptBridgeReady'
                , function () {
                    callback(WebViewJavascriptBridge)
                },
                false
            );
        }
    }

    // 擷取native發送的消息
    connectWebViewJavascriptBridge(function (bridge) {
        bridge.init(function (message, responseCallback) {
            alert(message);
            document.getElementById("show").innerHTML = ("native通過預設方法給js發來的資訊如下\n" + message);
            var data = {
                'JS Responds': 'js已經收到預設方法發送來的消息,native請知悉!'
            };

            if (responseCallback) {
                responseCallback(data);
            }
        });

        bridge.registerHandler("functionInJs", function (data, responseCallback) {
            alert(data); // typeof data  是  string
            document.getElementById("show").innerHTML = ("native通過functionInJs方法給js發來的資訊如下\n" + data);
            var str1 = JSON.parse(data);
            document.getElementById("text1").value = str1.name;
            document.getElementById("text2").value = str1.location.address;
            if (responseCallback) {
                var responseData = "js已經收到functionInJs方法發送來的消息,native請知悉!";
                responseCallback(responseData);
            }
        });
    })
   
</script>
</html>
           

3.引入jsbridge

project級build.gradle中加入jitpack的maven庫

allprojects {
    repositories {
        google()
        jcenter()
        // jitpack
        maven { url "https://jitpack.io" }
    }
}
           

app級build.gradle中加入dependencies依賴項

dependencies {
    ...
    implementation 'com.google.code.gson:gson:2.8.6'
}
           

4.Android的xml頁面代碼,貼就完了

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="@color/colorPrimary"
        android:orientation="vertical">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/colorPrimary"
            android:gravity="center"
            android:text="這裡是原生⬇️"
            android:textStyle="bold" />
        <Button
            android:id="@+id/btnDefaultTest"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="向js發送預設handleName的消息"
            android:textAllCaps="false" />
        <Button
            android:id="@+id/btnCustomTest"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="向js發送定制handleName=functionInJs的消息"
            android:textAllCaps="false" />
        <TextView
            android:id="@+id/tvTextInfo"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text=""
            android:textColor="#ffffff" />
    </LinearLayout>
    <TextView
        android:id="@+id/tvReloadUrl"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#f0ffff"
        android:gravity="center"
        android:text="這裡是網頁⬇️"
        android:textStyle="bold" />
    <com.github.lzyzsd.jsbridge.BridgeWebView
        android:id="@+id/testWebView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />
</LinearLayout>
           

布局截圖

Android端使用lzyzsd/JsBridge筆記1.背景2.開發工具3.js_native_contact_demo

運作截圖

Android端使用lzyzsd/JsBridge筆記1.背景2.開發工具3.js_native_contact_demo

5.activity中的代碼,貫徹一直的“優良作風”粘代碼(findById自己寫- -)

static class Location {
        String address;

        public Location(String address) {
            this.address = address;
        }
    }

 static class User {
        String name;
        Location location;
        String testStr;

        public User(String name, Location location, String testStr) {
            this.name = name;
            this.location = location;
            this.testStr = testStr;
        }
    }

           
// 設定浏覽器連結
        webView.setWebChromeClient(new WebChromeClient());
        // 加載url
        webView.loadUrl("file:///android_asset/demo.html");

        // 注冊js監聽回調,js通過預設方法發送消息給native時,可以在此處接收到
        webView.setDefaultHandler(new BridgeHandler() {
            @Override
            public void handler(String data, CallBackFunction function) {
                new AlertDialog.Builder(MainActivity.this).setMessage(data.toString()).show();
                tvTextInfo.setText(data.toString());
                function.onCallBack("Native已經收到了預設方法的消息,Js請知悉!");
            }
        });

        // 注冊js監聽回調,js通過 submitFromWeb 方法發送消息給native時,可以在此處接收到
        webView.registerHandler("submitFromWeb", new BridgeHandler() {
            @Override
            public void handler(String data, CallBackFunction function) {
                new AlertDialog.Builder(MainActivity.this).setMessage(data.toString()).show();
                tvTextInfo.setText(data.toString());
                function.onCallBack("Native已經收到了名為submitFromWeb方法的消息,Js請知悉!");
            }
        });

        // native主動發消息給js(預設handleName方法)
        btnDefaultTest.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                webView.send("這裡是native向js發送的預設消息!", new CallBackFunction() {
                    @Override
                    public void onCallBack(String data) {
                        tvTextInfo.setText(data.toString());
                        new AlertDialog.Builder(MainActivity.this).setMessage("通過預設方法發消息給js,并收到了js的回報如下\n" + data).show();
                    }
                });
            }
        });

        // native主動發消息給js(handleName = "functionInJs" 的方法)
        btnCustomTest.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                webView.callHandler("functionInJs", new Gson().toJson(new User("小白兔", new Location("大興安嶺"), "這裡是native向js發送的名字叫做'functionInJs'消息!")), new CallBackFunction() {
                    @Override
                    public void onCallBack(String data) {
                        tvTextInfo.setText(data.toString());
                        new AlertDialog.Builder(MainActivity.this).setMessage("通過functionInJs方法發消息給js,并收到了js的回報如下\n" + data).show();
                    }
                });
            }
        });

        // 重新加載網頁
        tvReloadUrl.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                webView.loadUrl("file:///android_asset/demo.html");
            }
        });
           

有興趣的建議跟着代碼弄個項目出來,自己點點思路會很清晰

本來還想解釋的,發現沒啥好說的,注釋寫的挺清楚了,就這樣吧,溜了!~