敞开成长之旅!这是我参与「日新方案 2 月更文应战」的第 10 天,点击查看活动概况

前言

曾经做电商项目的时分经常和前端打交道,由于许多商品概况页面都是来自H5,避免不了运用WebView。今天就来说说其时怎么运用WebView与前端做交互,有哪几种办法,并就运用中遇到的问题和一些功用的完结做一些阐明,希望能帮助咱们有效避坑。

已然打当作混合开发,那么必定提早了解过WebView这个控,这儿咱们就不提及那些基础的东西,直接来干货。

  • Webview中注入JS API

现在市面上很难找到基于Android4.2的机型了吧,所以咱们不必再担心接口走漏的状况。可直接运用addJavascriptInterface的办法,并在每个办法上增加@JavascriptInterface注解即可。这儿需求留意的是addJavascriptInterface办法的第一个入参是该接口,第二个是自定义的实体名。在前端那边就需求运用windows.{自定义实体名}.{接口内办法},这样就达到了前端调用移动端的效果。

//移动端注册前端需求运用的接口
addJavascriptInterface(JsInterface(this), "test")
class JsInterface(private val mContext: Context) {
    //供给给前端调用的办法
    @JavascriptInterface
    fun back() {
       (mContext as WebActivity).finish()
    }
}
//前端调用移动端办法
windows.test.back()

那么移动端怎么调用前端呢?,运用也很简略:

val json = "张三"
//移动端调用前端供给的onGetData办法,入参json
webView.loadUrl(
    "javascript:window.onGetData('"+ json+"')"
)

onGetData()办法便是前端接收的办法,需求留意的是loadUrl办法中由于传入的是字符串,在onGetData办法入参时需求运用单引号进行分割,不然编译器报错。

提到这儿不得不说的便是传图片、视频等文件的功用,以往都是运用前端调用原生办法,经过api翻开相机回来图片再以byte数字的办法回来给前端。但中途遇到一个状况便是前端的架构中运用的另外一种办法 openfile,曾经没遇到没关系,其实便是运用Webview设置WebChromeClient,前端运用openfile的时分Android端就会在onShowFileChooser办法中收到回调,这时分需求外部声明并赋值中onShowFileChooser中传回的ValueCallback,并初始化翻开相机获取图片信息。

private var valueCallback: ValueCallback<Array<Uri?>>? = null
webChromeClient =object :WebChromeClient(){
    override fun onShowFileChooser(
        p0: WebView?,
        filePathCallback: ValueCallback<Array<Uri?>>?,
        p2: FileChooserParams?
    ): Boolean {
        valueCallback = filePathCallback
        //初始化获取图片相关
        initPhoto()
        return true
    }
}

接着,运用刚刚得到的valueCallback传入得到的文件,这儿文件最终的格局必须运用Uri形式供给。

fun initPhoto() {
       ......
       override fun onResult(result: List<Uri?>) {
              valueCallback?.onReceiveValue(result)
              valueCallback==null
        }
        override fun onCancel() {
              valueCallback?.onReceiveValue(null)
              valueCallback=null
        }
}

这样前端就能在对应的回调中拿到移动端传过去的文件,需求留意的是valueCallback用后需求收回,不然下次运用会出现问题。

  • JsBridge

一款三方混合开发工具,装备少,两头都需求接入该三方库,运用简略:

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

需求留意的是,此时在Xml布局中要运用包名为:com.github.lzyzsd.jsbridge.BridgeWebView的webview,

//移动端供给test1办法
webView.registerHandler("test1", new BridgeHandler() {
    @Override
    public void handler(String data, CallBackFunction function) {
        function.onCallBack("submitFromWeb exe, response data from Java");
    }
});
//前端调用
WebViewJavascriptBridge.callHandler('test1', {'param': str1}, function(responseData) {
        document.getElementById("show").innerHTML = "send get responseData from java, data = " + responseData
    }
);
//前端注册test2办法
 WebViewJavascriptBridge.registerHandler("test2", function(data, responseCallback) {
        document.getElementById("show").innerHTML = ("data from Java: = " + data);
        var responseData = "Javascript Says Right back aka!";
        responseCallback(responseData);
    });
//移动端调用test2办法
webView.callHandler("test2", new Gson().toJson(user), new CallBackFunction() {
        @Override
        public void onCallBack(String data) {
        }
    });

这种办法还有一个优势便是前端不必考虑ios适配问题,只需求ios也接入该库就能满足仅需求一套代码就能适配两头的优点。

总结

Webview中注入JS API办法是官方控件供给的api,需求独自为前端注册一个接口用于前端拜访,可接收回来值,前端需求针对Android端进行适配。运用JsBridge办法网上有好几个三方库都可完结,各个端口需求接入同一个三方库,库里现已封装好各办法,前端可以一套代码完结移动端的适配。

敞开成长之旅!这是我参与「日新方案 2 月更文应战」的第 10 天,点击查看活动概况