Android与Js交互之JSBridge的使用

简介: 什么是JsBridgeJsBridge是js与Native之间进行通信的桥梁。为什么要使用JsBridgeAndroid4.2以下的addJavascriptInterface存在安全漏洞,虽然在Android4.

什么是JsBridge

JsBridge是js与Native之间进行通信的桥梁。

为什么要使用JsBridge

Android4.2以下的addJavascriptInterface存在安全漏洞,虽然在Android4.2之后用@JavascriptInterface代替了addJavascriptInterface但是由于兼容性和安全性问题,基本上我们不会再利用Android系统为我们提供的addJavascriptInterface方法或者@JavascriptInterface注解来实现,所以我们只能另辟蹊径,去寻找既安全,又能实现兼容Android各个版本的方案。

如何使用JsBridge

在Android中我们使用JsBridge开源项目来实现,实现JSBridge分为以下几个步骤。

步骤一:导入依赖

在项目gradle文件中添加
repositories {
        ...
        maven { url "https://jitpack.io" }
    }
在module的gradle中添加
dependencies {
    ...
    implementation 'com.github.lzyzsd:jsbridge:1.0.4'
}

步骤二:布局文件中用BridgeWebView代替WebView

<?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:orientation="vertical"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <EditText
        android:layout_width="match_parent"
        android:id="@+id/et"
        android:layout_height="wrap_content" />
    <Button
        android:layout_width="match_parent"
        android:text="调用js方法"
        android:id="@+id/bt"
        android:layout_height="wrap_content" />
    <com.github.lzyzsd.jsbridge.BridgeWebView
        android:id="@+id/webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </com.github.lzyzsd.jsbridge.BridgeWebView>
</LinearLayout>

步骤三:在Activity中对BridgeWebView进行配置

public class MainActivity extends AppCompatActivity {
    private EditText et;
    private Button bt;
    private BridgeWebView webview;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        et = (EditText) findViewById(R.id.et);
        bt = (Button) findViewById(R.id.bt);
        webview = (BridgeWebView) findViewById(R.id.webview);
        webview.setDefaultHandler(new DefaultHandler());
        webview.setWebChromeClient(new WebChromeClient());
        webview.loadUrl("file:///android_asset/test.html");
//      注册监听方法当js中调用callHandler方法时会调用此方法(handlerName必须和js中相同)
        webview.registerHandler("submitFromWeb", new BridgeHandler() {
            @Override
            public void handler(String data, CallBackFunction function) {
                Log.e("TAG", "js返回:" + data);
                //显示js传递给Android的消息
                Toast.makeText(MainActivity.this, "js返回:" + data, Toast.LENGTH_LONG).show();
                //Android返回给JS的消息
                function.onCallBack("我是js调用Android返回数据:" + et.getText().toString());
            }
        });
        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
//              调用js中的方法(必须和js中的handlerName想同)
                webview.callHandler("functionInJs", "Android调用js66", new CallBackFunction() {
                    @Override
                    public void onCallBack(String data) {
                        Log.e("TAG", "onCallBack:" + data);
                        Toast.makeText(MainActivity.this, data, Toast.LENGTH_LONG).show();
                    }
                });
            }
        });
    }
}

步骤四:编写html文件并对应Activity中的参数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <!-- Compiled and minified CSS -->
    <link rel="stylesheet" href="./materialize.min.css">
    <!-- Compiled and minified JavaScript -->
    <script src="./materialize.min.js"></script>
    <title>Test</title>
</head>
<body>
<div class="input-field col s6">
    <input placeholder="请输入数据" id="text1" type="text" class="validate">
</div>
<a class="waves-effect waves-light btn" onclick="testClick();">button</a>
</body>
<script>

         //js调用Android方法:接收Android传递过来的数据,并做处理

         function testClick() {

          //参数一:调用java中的方法   submitFromWeb是方法名,必须和Android中注册时候的方法名称保持一致
          //参数二:返回给Android端的数据,可以为字符串,json等信息
          //参数三:js接收到Android传递过来的数据之后的相应处理逻辑

            window.WebViewJavascriptBridge.callHandler(
               'submitFromWeb'
               , {'param': "JS成功接收到数据---"}
               , function(responseData) {
                    alert(responseData)
               }
           );
       }

       //JS注册事件监听
       function connectWebViewJavascriptBridge(callback) {
           if (window.WebViewJavascriptBridge) {
               callback(WebViewJavascriptBridge)
           } else {
               document.addEventListener(
                   'WebViewJavascriptBridgeReady'
                   , function() {
                       callback(WebViewJavascriptBridge)
                   },
                   false
               );
           }
       }

        //注册回调函数,第一次连接时调用 初始化函数
       connectWebViewJavascriptBridge(function(bridge) {
            //初始化
           bridge.init(function(message, responseCallback) {
               var data = {
                   'Javascript Responds': 'Wee!'
               };
               alert("jasdashjd");
               responseCallback(data);
           });


           //Android调用js方法:functionInJs方法名称需要保持一致 ,并返回给Android通知

           bridge.registerHandler("functionInJs", function(data, responseCallback) {
               alert(data);
               var data2 = document.getElementById("text1").value;
               var responseData = "我是Android调用js方法返回的数据---"+ data2;
               responseCallback(responseData);
           });
       })

</script>
</html>

步骤五:将html文件放入assets文件夹中

img_3a742e7b76d24447af61aee21e0a6ca9.png

效果展示:

img_656d8af83ff766177b5928b887e24626.gif

补充:

jsbridge调用默认的方法

●Activity代码

// 重写handler方法接收js的消息
 webview.setDefaultHandler(new DefaultHandler(){
            @Override
            public void handler(String data, CallBackFunction function) {
                Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show();
                function.onCallBack("Android收到了默认的消息");
            }
        });
        bt2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
//              发送信息给js,此处不需要配置handlerName
                webview.send(et.getText().toString().trim(), new CallBackFunction() {
                    @Override
                    public void onCallBack(String data) {
//                      接收js的回调数据
                        Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });

●html代码

 //初始化
           bridge.init(function(message, responseCallback) {
               var data = {
                   'Javascript Responds': 'Wee!'
               };
               //添加代码用来弹出Activity发送的默认消息
               alert(message);
               responseCallback(data);
           });
// 加入如下方法用于发送消息给Activity
function testClick2() {
var data2 = document.getElementById("text1").value;
          //参数一:调用java中的方法   submitFromWeb是方法名,必须和Android中注册时候的方法名称保持一致
          //参数二:返回给Android端的数据,可以为字符串,json等信息
          //参数三:js接收到Android传递过来的数据之后的相应处理逻辑

            window.WebViewJavascriptBridge.send(
        data2,
        function(responseData){
            //java中DefaultHandler所实现的方法中callback所定义的入参
            alert(responseData);
        }
    );
       }
img_22fcc411b2f0aa9bdae023ad910518ca.gif

案例源码

目录
相关文章
|
2月前
|
开发框架 JavaScript 前端开发
揭秘:如何让你的asp.net页面变身交互魔术师——先施展JavaScript咒语,再引发服务器端魔法!
【8月更文挑战第16天】在ASP.NET开发中,处理客户端与服务器交互时,常需先执行客户端验证再提交数据。传统上使用ASP.NET Button控件直接触发服务器事件,但难以插入客户端逻辑。本文对比此法与改进方案:利用HTML按钮及JavaScript手动控制表单提交。后者通过`onclick`事件调用JavaScript函数`SubmitForm()`来检查输入并决定是否提交,增强了灵活性和用户体验,同时确保了服务器端逻辑的执行。
40 5
|
1月前
|
JavaScript 前端开发
JavaScript 与 DOM 交互
【9月更文挑战第01天】
22 2
|
2月前
|
JavaScript 前端开发 UED
Vue.js动画魔法:解锁流畅过渡,让每一次交互都成为用户心中的小确幸!
【8月更文挑战第30天】在Vue.js中,动画与过渡效果不仅是视觉点缀,更是提升用户体验的关键。通过流畅的动态效果,应用的互动性和吸引力得以增强,从而提高用户满意度和参与度。`&lt;transition&gt;`和`&lt;transition-group&gt;`组件结合CSS过渡,可轻松实现元素的进入、离开及列表变化动画。合理的性能优化,如使用硬件加速,能避免页面卡顿,确保动画既美观又高效。下面是一个简单的淡入淡出效果示例,展示了如何利用Vue.js实现平滑的动画过渡。总之,恰当的动画设计能显著提升应用的用户体验。
41 0
Vue.js动画魔法:解锁流畅过渡,让每一次交互都成为用户心中的小确幸!
|
2月前
|
XML Android开发 UED
"掌握安卓开发新境界:深度解析AndroidManifest.xml中的Intent-filter配置,让你的App轻松响应scheme_url,开启无限交互可能!"
【8月更文挑战第2天】在安卓开发中,scheme_url 通过在`AndroidManifest.xml`中配置`Intent-filter`,使应用能响应特定URL启动或执行操作。基本配置下,应用可通过定义特定URL模式的`Intent-filter`响应相应链接。
90 12
|
2月前
|
Devops 持续交付 测试技术
JSF遇上DevOps:开发流程将迎巨变?一篇文章带你领略高效协同的魅力!
【8月更文挑战第31天】本文探讨了如何在JavaServer Faces(JSF)开发中融入DevOps文化,通过持续集成与部署、自动化测试、监控与日志记录及反馈机制,提升软件交付速度与质量。文中详细介绍了使用Jenkins进行自动化部署、JUnit与Selenium进行自动化测试、ELK Stack进行日志监控的具体方法,并强调了持续改进的重要性。
30 0
|
2月前
|
JSON Android开发 数据格式
Android项目架构设计问题之实现交互响应的结构化处理如何解决
Android项目架构设计问题之实现交互响应的结构化处理如何解决
14 0
|
2月前
|
前端开发 JavaScript
前端 JavaScript 与 HTML 怎么实现交互
前端 JavaScript 与 HTML 怎么实现交互
|
2月前
|
存储 JavaScript 前端开发
2D物理引擎 Box2D for javascript Games 第三章 刚体的交互
2D物理引擎 Box2D for javascript Games 第三章 刚体的交互
|
3月前
|
移动开发 JavaScript Java
Android与JS互相调
Android与JS互相调
|
3月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的高校后勤网上报修系统安卓app附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的高校后勤网上报修系统安卓app附带文章源码部署视频讲解等
39 0
下一篇
无影云桌面