web前端入门到实战:Js和原生相互调用总结-创新互联

一、前言

现在市面上有一些app是通过原生ios、Android加载一个网页实现的,如图所示,这样的app我们称之为 Hybrid App

专业领域包括做网站、网站设计、商城网站建设、微信营销、系统平台开发, 与其他网站设计及系统开发公司不同,成都创新互联的整合解决方案结合了帮做网络品牌建设经验和互联网整合营销的理念,并将策略和执行紧密结合,为客户提供全网互联网整合方案。

那么为什么要用 hybrid app呢? 个人认为的原因有两点:

1.提高开发效率,以钉钉为例在涉及到一些OA操作比如打卡,请假等功能的时候,显然一个嵌入一个网页就能够满足需求,如果在让IOS和Android再去各自开发一套那么效率就很低了。
2.提高迭代效率。以商城为例,商城页面会根据市场情况实时发生变化,比如遇到各种节假日活动做促销。那么这个时候如果用原生,那么迭代等用户去升级可能这个活动都已经过了,但是用嵌套webview嵌套一个网页只需要网页做出修改hybrid app内的web页面就会马上修改,这样效率就非常高了。

hybrid app 实际上就是利用原生的组件webview加载一个url再让js和原生相互调用实现各种功能,那么接下来我就把js和原生相互调用的情况做一个总结。

二、原生api实现:js和原生相互调用

要想让js和原生相互调用,对于webview最基本的一个设置就是要允许js脚本执行

 WebSettings settings = mWebView.getSettings();
 settings.setJavaScriptEnabled(true);

(一)、js调用原生

假设我现在有一个需求:点击web中的一个按钮,将web中的值传递给原生并在TextView组件中显示出来。那么这个需求怎么实现呢?

第一步:在java代码中定义js要调用的方法

  // 定义JS需要调用的方法    // 被JS调用的方法必须加入@JavascriptInterface注解    @JavascriptInterface    public void sendMsg(String msg) {//        Log.i(TAG, "JS调用了Android的hello方法" + msg);//        Toast.makeText(mContext, "JS调用了Android的hello方法" + msg, Toast.LENGTH_SHORT).show();        //为了方便拿到上下文和ui组件,写一个回调接口。        mJSBridge.sendMsg(msg);    }

这里需要说明的是,1.要在方法上面添加“@JavascriptInterface”注解,2.定义的方法必须是公共方法

第二步:给webview添加js脚本接口。

 mWebView.addJavascriptInterface(jsInterface, "Android_Interface");

void addJavascriptInterface (Object object, String name),这个方法有两个参数,第一个是一个注入webview中js上下文的java对象,第二个参数是在js脚本中来暴露的名称对象,也就是说,这里写什么,待会在js调用原生的时候就写什么。

第三步:用js调用原生方法

function sendMsg() {
    Android_Interface.sendMsg("你好,这是要传递的参数")
}
web前端开发学习Q-q-u-n: 784783012 ,分享学习的方法和需要注意的小细节,不停更新最新的教程和学习方法
(从零基础开始到前端项目实战教程,学习工具,职业规划)

(二)、原生调用js

原生调用js中的方法,例如,在这里我们实现点击原生中的按钮来改变web中div的样式。那么这个该如何实现呢?

这里直接使用webview的api就能够实现。Android中的代码如下: 

// 第一种调用js中代码的方法
// mWebView.loadUrl("javascript:beStronger()");
//第二种调用js中代码的方法,同时传值过去
        mWebView.evaluateJavascript("javascript:beStronger(‘" + str + "‘)", new ValueCallback() {
            @Override
            public void onReceiveValue(String value) {
                //此处为 js 返回的结果
                Toast.makeText(H5Activity.this, value, Toast.LENGTH_SHORT).show();
            }
        });

在web中的代码如下:

function beStronger(value) {
    let box = document.getElementById("box");
    // box.innerText = value;
    box.className = "box2";
    box.innerText=value;
    return "小明你好"
}

当点击原生按钮web中的div就会发生变化。

web前端入门到实战:Js和原生相互调用总结

(三)、可能存在的安全性问题

但是在js调用原生的时候,可能会存在安全问题。具体的产生原因和解决办法可以参考这一篇文章。《你不知道的 Android WebView 使用漏洞》。那如果要做的app对安全性要求极高,该怎么办呢?这里推荐一个Android的第三方库:JSBridge

三、第三方库实现:js和原生相互调用

关于这个第三方库的介绍,在说明文件中已经说得很清楚了:该库是js和java相互调用的桥梁,它为js和java之间相互调用提供了一个安全且便捷的方法。

(一)、引入第三方库

第一步是在 app/build.gradle 文件中引入该库。

 repositories {
        // ...
        maven { url "https://jitpack.io" }
    }
dependencies {
    .....  
    compile ‘com.github.lzyzsd:jsbridge:1.0.4‘
}

然后在布局中添加自定义的组件,BridgeWebView,该组件继承自原生的WebView组件。

 
    
    
       web前端开发学习Q-q-u-n: 784783012 ,分享学习的方法和需要注意的小细节,不停更新最新的教程和学习方法
(从零基础开始到前端项目实战教程,学习工具,职业规划)

(二)、js调用原生

这套框架使用的核心就是:handler的注册的调用。

要先实现js调用原生,那么首先要在java原生中“注册handler”,代码如下

//注册handlerwebView.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");
        }
    });

在注册了handler以后,就可以在js代码中调用指定的handler了,例如上面我们注册的handler是“submitFromWeb”,js 可以通过如下的方式调用java中注册的handler。

 WebViewJavascriptBridge.callHandler(
        ‘submitFromWeb‘
        , {‘param‘: str1}
        , function(responseData) {
            document.getElementById("show").innerHTML = "send get responseData from java, data = " + responseData
        }
    );

(三)、原生调用js

要先实现原生调用js,那么首先也要在js中注册handler

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

在js中注册了handler以后,在java代码中就能够调用指定名称的handler 

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

        }
    });

(四)、需要注意的地方

这个库将注册一个 WebViewJavascriptBridge 对象给window 对象。那么在你的js代码中,在使用WebViewJavascriptBridge对象之前,你必须检测WebViewJavascriptBridge对象是否存在。如果WebViewJavascriptBridge对象不存在,你可以监听WebViewJavascriptBridgeReady事件,如下所示: 

  if (window.WebViewJavascriptBridge) {
        //do your work here
    } else {
        document.addEventListener(
            ‘WebViewJavascriptBridgeReady‘
            , function() {
                //do your work here
            },
            false
        );
    }

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


新闻名称:web前端入门到实战:Js和原生相互调用总结-创新互联
URL网址:http://pwwzsj.com/article/gsicc.html