用AIDL完成可跨进程通信的WebView框架

·  阅读 667

至今为止做过的项目里,H5和android的通信都是一个个方法写好,用注解标识,然后互相调用,而且还都写在同一个地方,甚至有些没把WebView放到另一个进程中去,而且方法多了,显得特别臃肿和混乱。之前写过一个可跨进程的WebView框架,经过学习之后做出了改进。虽然还有很多可优化的点,这就算先记录下来吧

Github传送门

Github传送门

框架结构图

各个类之间的关系就是这样,调用流程也差不多就是这样 image.png

使用方法

创建一个Commond指令

一个指令为一个方法,又或者你可以创建一个通用指令,再或者你可以进行封装都可以。

这里通过打开一个Activity的简单指令来介绍

  • 首先,一个指令必须继承Command并实现两个方法,CommandName执行方法(指令名称要和H5端保持一致的)
  • 其次使用 AutoService 注解去标志他属于 Command.class,方便后续查找(AutoService可通过自定义注解替代)
  • 参数callback属于AIDL文件,如果有数据回调可以使用,没有可以不用管

image.png

执行一个指令

指令在android端创建,接着等着H5端来调用我们的方法

  • 如下,H5端想调用上面创建的指令,只需要在方法中,传入指令名称'openActivity'和message参数,android端就可以在本地指令集中找到对应指令,并根据message执行相应操作

image.png

image.png

这样看起来是不是清爽很多?只有一个个指令,可以写到同一个文件中,也可以分开一个个写,甚至可以单独创建一个module去专门存放指令,我是感觉比一个方法一个@JavascriptInterface注解清爽了不少

Web调用Main的分析

首先原理是使用了AIDL,但是这里就不对AIDL进行阐述了。网上已经有很多优秀的文章了。 不过为了方便理解,就先这样简单的认为吧

  • AIDL 就是中间人,接口
  • Stub 实现方,实现AIDL中的方法
  • Proxy 就是遥控器,拿到该对象就能调用AIDL里定义的方法了

AIDL就好比一个菜单,里面有定义好的菜名。 Proxy遥控器就可以根据AIDL菜单去点菜。 Stub 就像一个厨师,你点的菜,最终AIDL会告诉Stub,让他去做具体实现

还是先来看看两个AIDL文件吧

两个AIDL文件

  • IWebviewProcessToMainProcessInterface (简称IWebToM)

这个AIDL简单,里面只有一个方法,并且接受三个参数

分别是 指令名称,携带的参数,和另一个AIDL对像 image.png

  • ICallbackFromMainprocessToWebViewProcessInterface (简称CallbackMToWeb)

这个也很简单,就是一个回调函数的名称,和一个回调的数据

image.png

入口takeNativeAction

这是H5调用android方法的入口,可以看到将传递过来的数据转换成JsParam.class后,就直接交给WebCommandDispatcher处理了 image.png

WebCommandDispatcher 遥控器

可以看到 WebCommandDispatcher 中存放了一个IWebToM对象,并且启动了Service

image.png

接着通过 IWebToM.Stub.asInterface(service) 方法就能得到 AIDL的Proxy对象,拿到遥控器

image.png

也就是说 WebCommandDispatcher 就可以执行IWebToM定义的方法了 image.png

也就是调用Proxy对象中的 handleWebCommand 方法 image.png

MainCommandsManager Stub实现类

可以看到,是直接继承IWebToM.Stub的,并且之前使用的 AutoService 注解在这里也会用到,

她会帮我们收集通过 AutoService 打上了 Command 标志的类,然后保存起来 image.png

然后遥控器调用方法时,就会调用到我们复写的方法,然后在收集到的Command指令集中查找,找到对应指令执行方法

image.png

Main回调Web的分析

我们知道回调是通过CallbackMToWeb这个AIDL对象来完成的,那么谁是遥控器,谁是实现类呢?

CallbackMToWeb的实现类

回到WebCommandDispatcher中的方法,可以看到,在调用IWebToM的方法时,就已经传入了一个CallbackMToWeb实现类

image.png

按照上面的流程,这个Stub实现类,就会一直传递给某个具体指令,然后调用就会回到onResult方法,而方法中直接将回调的数据交给了 webView 处理, 这样就完成了Main到Web的回调了 image.png

CallbackMToWeb的遥控器在哪里

是不是全程没看到通过 Stub.asInterface 方法拿到遥控器,既然他能调用起来,就说明内部帮我们做了转换呗。

那我们就进入到AIDL中,系统帮我们生成CallbackMToWeb文件,直接点击就能找到他的调用处 image.png

是在系统帮我们生成的IWebToM文件中,handleWebCommand调用时,会帮我们生成一个Proxy对象,然后再传递出去,所以说但我们传递到某个具体指令时,就已经是Proxy对象了,这样整个流程才能走得通

image.png

结尾

这个框架只是简单框架,因为总是忘记思路,所以做一下记录。还有很多地方是可以优化的,欢迎在评论区指出交流~

分类:
Android
标签:
分类:
Android
标签: