简化Android与JS交互,JsBridge框架全面解析

今日科技快讯

近日,滴滴顺风车披露了一组数字,预测春运前后,跨城出行以7天为一个周期,呈“潮汐式”变化。2月13号,有将近100万人乘滴滴顺风车踏上归途;除夕当天,还有近40万在回家的顺风车上。返程巅峰集中在2月23日前后,23日预计有超过110万人乘坐滴滴顺风车返回工作岗位。

作者简介

本篇文章来自juexingzhe的投稿。主要介绍了Android与JS的交互框架JsBridge源码分析的相关知识,希望对大家有所帮助!

juexingzhe的博客地址:

https://www.jianshu.com/u/ea71bb3770b4

前言

在Android开发中,由于Native开发的成本较高,H5页面的开发更灵活,修改成本更低,因此前端网页JavaScript(下面简称JS)与Java之间的互相调用越来越常见。

JsBridge就是一个简化Android与JS通信的框架,源码地址:

https://github.com/lzyzsd/JsBridge

正文

我们今天通过一个简单例子来分析下开源框架JsBridge的源码。例子的代码我也放在Github,有需要的可以seesee:

https://github.com/juexingzhe/Android_JS

例子很简单,随便输入信息登陆,会加载一个H5页面,在H5界面点击按钮,Java执行getUserInfo()然后将UserInfo回传给JS,H5页面再显示UserInfo。

1.png

2.png

3.png

JS调用Android基本有下面三种方式

webView.addJavascriptInterface()

WebViewClient.shouldOverrideUrlLoading()

WebChromeClient.onJsAlert()/onJsConfirm()/onJsPrompt() 方法分别回调拦截JS对话框alert()、confirm()、prompt()消息

Android调用JS

webView.loadUrl();

webView.evaluateJavascript()

常用方法的使用后面例子中会用到,更细节的介绍各位同学可以去网上搜搜看看。

JsBridge使用

我们先来看下Java层的代码,首先引入依赖和仓库

准备工作就是这样,下面可以开始撸代码,首先就是点击按钮登陆,这个简单:

布局文件中要使用BridgeWebView:

在跳转后的页面,获取登陆信息并存储,再通过loadUrl加载H5页面:

主要是要注册Handler,供JS调用,getUserInfo就是注册供JS调用的Handler的id,data是JS传过来的参数,CallBackFunction 函数中需要把JS需要的response返回给JS

Java层的代码就这么简单,下面看下JS层工作:

首先需要一个js文件,我们写一个getuserinfo.html文件放在assets目录下,文件内容,不建议把js代码直接放在html文件中,我为了方便直接就写在这了。代码放了两个段落,一个类似于TextView用来显示用户信息,一个Button。点击按钮会调用callHandler,三个参数和Java层一一对应,在Java层返回的时候,会调用function(responseData)函数,显示用于信息。

使用基本就是这样了,可以看出来JsBridge通过封装,JS和Java之间的通信只需要实现两个步骤,使用起来很方便。

JsBridge源码分析

分析之前我把JS调用Java画了个简易交互图,Java调用JS的过程类似:

4.png

是不是感觉反而更复杂了???其实只要捉住主要的三点,JsBridge就原形毕露:

Android调用JS是通过loadUrl(url),url中可以拼接要传给JS的对象

JS调用Android是通过shouldOverrideUrlLoading

JsBridge将沟通数据封装成Message,然后放进Queue,再将Queue进行传输

接下来我们来一步一步跟踪上面例子的调用过程:

JS层点击按钮调用callHandler

handlerName,Java和JS要一致,data是Java层handlerName函数执行的参数。responseCallback是Java执行完handlerName返回时,JS回调的接口,是JS执行

callHandler会调用_doSend。如果JS需要回调,就将回调的callbackId放进message中,Java执行完会传回callbackId,这里是cb_1_1495182409011,构造完message放进队列sendMessageQueue。通过iframe属性给Java发送通知消息,消息结构为:

yy://QUEUE_MESSAGE/

Java收到通知消息

WebView在shouldOverrideUrlLoading拦截到url:yy://QUEUE_MESSAGE/

然后会执行webView.flushMessageQueue(),在主线程执行loadUrl通知JS层推送队列到Java;

JS 发送Request Queue

执行_fetchQueue,将sendMessageQueue转化成JSON。通过iframe属性给Java发送通知消息。

Java收到调用通知

进行处理并发送Response Queue到JS,WebView在shouldOverrideUrlLoading会拦截到url,执行webView.handlerReturnData(url);根据函数名_fetchQueue拿到之前注册的回调函数CallBackFunction returnCallback,执行回调函数,并且从注册中移除。

接下来就是对Request Queue的解析然后找到JS希望调用Handler并且执行,代码中我写了注释,可以直接看:

那么这个handler是什么?就是Java调用registerHandler注册的getUserInfo

上面的function就是在flushMessageQueue 解析时构造的responseFunction,在message中包括JS层需要回调的函数Id,然后就是getUserInfo执行的结果。调用queueMessage

通过构造String指令,然后loadUrl执行JS代码,注意对象也是通过这样方式传递过去的,就类似调用本地函数,不发起网络请求

其中

JS收到Response JSON

来到_handleMessageFromNative

最后都会调用到_dispatchMessageFromNative,由于是JS主动调用Java,因此有responseId,执行registerHandler时传入的CallBack,也就是显示用户信息。我在代码里加了注释,很容易看懂。

源码的分析就到这结束了,代码不多,但是封装的接口很是好用。

总结

最后总结下,使用上很方便主要两个步骤

被调用方注册Handler

调用方调用Handler

原理上还是那三句话,请原谅我从上面直接copy过来:

Android调用JS是通过loadUrl(url),url中可以拼接要传给JS的对象

JS调用Android是通过shouldOverrideUrlLoading

JsBridge将沟通数据封装成Message,然后放进Queue,再将Queue进行传输

好了,今天我们JsBridge的使用和源码分析就到这了,谢谢!

文中例子的链接:

https://github.com/juexingzhe/Android_JS

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180125G03N3000?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励