欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JSBridge框架学习小结

程序员文章站 2024-03-21 16:58:34
...

JSBridge框架学习小结

JsBridge的github地址:JsBridge链接

JSBridge框架学习小结

一、前言

应用开发必备的基础知识,学的比较浅,做个小结,其中不包含图片文件上传的部分。

二、studio导包

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

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

三、代码部分

1.activity_main.xml布局

这里主要是在布局中添加框架中的BridgeWebView控件。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main"
    android:layout_width="match_parent" android:layout_height="match_parent"
    tools:context="com.example.myapplication.MainActivity">

    <!-- button 演示Java调用web -->
    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:text="演示Java调用web"
        android:layout_height="48dp"
        />

    <!-- webview 演示web调用Java -->
    <com.github.lzyzsd.jsbridge.BridgeWebView
        android:id="@+id/webView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </com.github.lzyzsd.jsbridge.BridgeWebView>
</RelativeLayout>

2.MainActivity代码

这里主要分3步:
1、加载url.

webView.loadUrl("file:///android_asset/demo.html");

2、注册handler,registerHandler();
参数:registerHandler(标识,回调接口);

 webView.registerHandler("submitFromWeb", new BridgeHandler() {

            @Override
            public void handler(String data, CallBackFunction function) {
            //data为js数据,我们可以解析等,处理逻辑后,用下面的方法回传数据给js。
                function.onCallBack("h5你好,我处理好了,给你返回这句话打个招呼");
            }

        });

3、定义callHandler,这是java主动获取h5中的数据。可以在初始化界面时候从h5拿数据时使用。
参数:标识,实体类对象,回调接口(在这里拿到js给你的数据data)

webView.callHandler("functionInJs", new Gson().toJson(user), new CallBackFunction() {
            @Override
            public void onCallBack(String data) {
                Log.i(TAG,data);
            }
        });

4、当h5调用send()发送消息的时候,调用此段代码。(看需求加此步骤)
参数:data,h5给java的数据,处理好了可以调用function.onCallBack()返回给h5

webView.setDefaultHandler(new BridgeHandler(){
            @Override
            public void handler(String data, CallBackFunction function) {
                Log.i(TAG,data);
                function.onCallBack("你好JS,我已经处理好了数据,返回给你个信号给你");

            }
        });

3.html5代码

因为和java方式差不多,所以简略说一下:
1、注册Handler,等待java调用

bridge.registerHandler("functionInJs", function(data, responseCallback) {
                document.getElementById("show").innerHTML = ("data from Java: = " + data);
                var responseData = "Javascript Says Right back aka!";
                responseCallback(responseData);
            });

2、h5发送消息给java,主调handler,通过callHandler实现。

window.WebViewJavascriptBridge.callHandler('submitFromWeb', {'param': '中文测试'} 
               , function(responseData) {

                }
            );

3、h5发送消息给java,通过send()实现

window.WebViewJavascriptBridge.send(data , function(responseData) {  

                }
            );

最后贴上全h5和java全代码
demo.html代码:

<html>
    <head>
        <meta content="text/html; charset=utf-8" http-equiv="content-type">
        <title>
            js调用java
        </title>
    </head>

    <body>
        <p>
            <xmp id="show">
            </xmp>
        </p>
        <p>
            <xmp id="init">
            </xmp>
        </p>
        <p>
            <input type="text" id="text1" value="用户名(username)" />
        </p>
        <p>
            <input type="text" id="text2" value="password" />
        </p>
        <p>
            <input type="button" id="enter" value="发消息给Native" onclick="testClick();"
            />
        </p>
        <p>
            <input type="button" id="enter1" value="调用Native方法" onclick="testClick1();"
            />
        </p>
        <p>
            <input type="button" id="enter2" value="显示html" onclick="testDiv();" />
        </p>
        <p>
            <input type="file" value="打开文件" />
        </p>
    </body>
    <script>
        function testDiv() {
            document.getElementById("show").innerHTML = document.getElementsByTagName("html")[0].innerHTML;
        }
        //方法1:通过send(),发消息给Native(button)的点击事件,html中button,传递到JAVA
        function testClick() {
            var str1 = document.getElementById("text1").value;
            var str2 = document.getElementById("text2").value;

            var data = {id: 1, content: "这是一个图片 <img src=\"a.png\"/> test\r\nhahaha"};
            //动作:点击html中button,传递数据给JAVA
            //参数:data,回调接口
            //JAVA代码响应方法:webView.setDefaultHandler(new BridgeHandler(){ handler(String data, CallBackFunction function)}
            window.WebViewJavascriptBridge.send(
                data
                , function(responseData) {
                    document.getElementById("show").innerHTML = "repsonseData from java, data = " + responseData
                }
            );

        }
        //方法2:通过callHandler(),调用Native方法(button)的点击事件,html中button,传递到JAVA
        function testClick1() {
            var str1 = document.getElementById("text1").value;
            var str2 = document.getElementById("text2").value;

            //动作:点击html中button,传递数据给JAVA
            //参数:标识,data,回调接口
            //JAVA代码响应方法:webView.registerHandler("submitFromWeb", new BridgeHandler() { handler(String data, CallBackFunction function)}
            window.WebViewJavascriptBridge.callHandler(
                'submitFromWeb'
                , {'param': '中文测试'}
                , function(responseData) {
                    document.getElementById("show").innerHTML = "send get responseData from java, data = " + responseData
                }
            );
        }

        function bridgeLog(logContent) {
            document.getElementById("show").innerHTML = logContent;
        }

        function connectWebViewJavascriptBridge(callback) {
            if (window.WebViewJavascriptBridge) {
                callback(WebViewJavascriptBridge)
            } else {
                document.addEventListener(
                    'WebViewJavascriptBridgeReady'
                    , function() {
                        callback(WebViewJavascriptBridge)
                    },
                    false
                );
            }
        }

        connectWebViewJavascriptBridge(function(bridge) {
            bridge.init(function(message, responseCallback) {
                console.log('JS got a message', message);
                var data = {
                    'Javascript Responds': '测试中文!'
                };
                console.log('JS responding with', data);
                responseCallback(data);
            });
            //注册handler等待java代码调用
            //初始化时获取数据是调用此处代码
            //参数:标识,要传递到JAVA的数据,回调方法。
            //JAVA代码响应的方法:webView.callHandler("functionInJs", new Gson().toJson(实体类对象), new CallBackFunction(){onCallBack(String data)}
            bridge.registerHandler("functionInJs", function(data, responseCallback) {
                document.getElementById("show").innerHTML = ("data from Java: = " + data);
                var responseData = "Javascript Says Right back aka!";
                responseCallback(responseData);
            });
        })
    </script>

</html>

下面是整个MainAvtivity的代码:

package com.example.myapplication;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.widget.Button;

import com.github.lzyzsd.jsbridge.BridgeHandler;
import com.github.lzyzsd.jsbridge.BridgeWebView;
import com.github.lzyzsd.jsbridge.CallBackFunction;
import com.google.gson.Gson;

public class MainActivity extends Activity implements View.OnClickListener {

    private final String TAG = "MainActivity";

    BridgeWebView webView;

    Button button;

    int RESULT_CODE = 0;

    ValueCallback<Uri> mUploadMessage;

    static class Location {
        String address;
    }

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

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        webView = (BridgeWebView) findViewById(R.id.webView);

        button = (Button) findViewById(R.id.button);

        button.setOnClickListener(this);
//        webView.setDefaultHandler(new DefaultHandler());

        //此部分为webview上传文件的回调
        webView.setWebChromeClient(new WebChromeClient() {

            @SuppressWarnings("unused")
            public void openFileChooser(ValueCallback<Uri> uploadMsg, String AcceptType, String capture) {
                this.openFileChooser(uploadMsg);
            }

            @SuppressWarnings("unused")
            public void openFileChooser(ValueCallback<Uri> uploadMsg, String AcceptType) {
                this.openFileChooser(uploadMsg);
            }

            public void openFileChooser(ValueCallback<Uri> uploadMsg) {
                mUploadMessage = uploadMsg;
                pickFile();
            }
        });

        webView.loadUrl("file:///android_asset/demo.html");

        //对应html中的方法1
        //获取JS  send()方法发送过来的数据
        //window.WebViewJavascriptBridge.send();
        webView.setDefaultHandler(new BridgeHandler(){
            @Override
            public void handler(String data, CallBackFunction function) {
                Log.i(TAG,"ddss"+data);
                function.onCallBack("你好JS,我已经处理好了数据,返回给你个信号给你");
            }
        });
        //对应html中的方法2
        //<Btn调用Native>点击webview控件,调用java方法,通过“submitFromWeb”标识传递数据,数据为实现方法的参数data
        //相关JS方法testClick1()->window.WebViewJavascriptBridge.callHandler("submitFromWeb","data",callback)
        webView.registerHandler("submitFromWeb", new BridgeHandler() {

            @Override
            public void handler(String data, CallBackFunction function) {
                Log.i(TAG, "handler = submitFromWeb, data from web = " + data);
                function.onCallBack("submitFromWeb exe, response data 中文 from Java");
            }

        });


        User user = new User();
        Location location = new Location();
        location.address = "SDU";
        user.location = location;
        user.name = "大头鬼";
        //初始化启动时,获得JS传递过来的数据,对应JS中connectWebViewJavascriptBridge(function(bridge)-> bridge.registerHandler()
        webView.callHandler("functionInJs", new Gson().toJson(user), new CallBackFunction() {
            @Override
            public void onCallBack(String data) {
                Log.i(TAG,"ddss-ccc"+data);
            }
        });
//        webView.send("hello");

    }

    public void pickFile() {
        Intent chooserIntent = new Intent(Intent.ACTION_GET_CONTENT);
        chooserIntent.setType("image/*");
        startActivityForResult(chooserIntent, RESULT_CODE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        if (requestCode == RESULT_CODE) {
            if (null == mUploadMessage) {
                return;
            }
            Uri result = intent == null || resultCode != RESULT_OK ? null : intent.getData();
            mUploadMessage.onReceiveValue(result);
            mUploadMessage = null;
        }
    }
    //点击JAVA中的btn事件,
    // 响应bridge.registerHandler("functionInJs", function(data, responseCallback)
    @Override
    public void onClick(View v) {
        if (button.equals(v)) {
            webView.callHandler("functionInJs", "data from Java", new CallBackFunction() {

                @Override
                public void onCallBack(String data) {
                    // TODO Auto-generated method stub
                    Log.i(TAG, "reponse data from js " + data);
                }

            });
        }

    }
}

四、总结

要注意几点:
1.与h5的标识要一致。
2.使用成对,callhandler与registerHandler。
3.如果有上传文件图片失败,可能是5.0以上的系统,在WebChromeClient中应实现onShowFileChooser()方法。注意适配问题!