web和android端交互简单封装:JsBridge

本文介绍了一种通过JsBridge封装Android与Web视图间的交互方式,旨在解决传统交互方式带来的扩展性和兼容性问题。通过注解和自动生成的交互类,实现了自动JSON解析、动态扩展action及简便的绑定方法。文中详细阐述了实现过程,并提供了测试案例。
摘要由CSDN通过智能技术生成
1、背景

公司项目是通过webView.addJavascriptInterface(Object obj, String
interfaceName)进行web和原生的交互的,android端通常会定义类似以下的多个方法,这样做的好处是便于阅读,一看便知方法是干什么的,需要什么参数;坏处是不便于扩展,一旦web端传错参数,或者调了一个android端没有的方法时,会导致各种问题,每当需要扩展时,web端总是需要考虑android端的版本兼容问题,因此考虑一个通用的方法来处理双方的交互(正好前些日子学了Javapoet和apt没东西练手hhhhh)。

    @JavascriptInterface
    public void func(){
    }

    @JavascriptInterface
    public void func(int a, int b){
   }

    @JavascriptInterface
    public void func1(int a, String b){
    }
2、交互

Android端只暴露一个方法给web端调用,双方约定好数据类型,比如一个json字符串,action代替原来的方法用作请求标志,data作为扩展参数,如

{
   
	"action" :REQUEST_PLAY_VIDEO,
	"data" : {
   
			"url" : "http://xxxx"
     }
}

同时暴露一个接口出来用作交互,如

  @JavascriptInterface
  public void request(String request) {
   }

这样,交互问题就解决了,当web需要扩展时,只需往json字符串里添加额外的参数即可,android端这边解析json,由于低版本没有解析额外的参数因此会忽略掉,不会导致网页报错等问题,高版本或者补丁包添加参数处理即可。到这里基本可以了,但,还是会存在一些问题:

  1. 参数是json字符串,要解析
  2. 解析后要判断action,做相应的处理,如果带数据data,还要解析转成Java对象
  3. 简单的判断action免不了switch,每添加一个方法就要写一个case过于麻烦

基于以上问题,把交互方式封装一下。

3、实现

封装一个简单的JsBridge,要实现的功能如下:

  1. 自动解析json,android端拿到的是对应的Java对象
  2. 简单的扩展action的方式
  3. 简单的绑定方式,如JsBridge.bind(webview, object)
  4. 其他,如错误处理等

思路很简单:通过注解标记与web交互的类和action对应的实现方法,通过Javapoet和apt生成相应的类,该类包含了真正的交互方法(@JavascriptInterface标记的),在该方法里解析json参数得到action,switch判断action对应的实现方法,再调用即可。

3.1、定义一些约束
3.1.1、注解
/**
 * js和android互相交互的js名
 * author : pxq
 * date : 19-10-24 下午9:39
 */
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface Bridge {
   
    //js交互名
    String name();
    //交互方法
    String jsMethod();
}

/**
 * js请求android端的action
 * author : pxq
 * date : 19-10-24 下午9:38
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface JsAction {
   
    //action名
    String value();
}

/**
 * Js Request异常,如解析失败等
 * author : pxq
 * date : 19-10-26 下午2:27
 */
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.METHOD)
public @interface JsError {
   
}

/**
 * 未处理的Js Request
 * author : pxq
 * date : 19-10-26 下午2:25
 */
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.METHOD)
public @interface UnHandle {
   
}
3.1.2、获取interfaceName的接口

注意到webView.addJavascriptInterface(Object obj, String interfaceName)需要一个interfaceName,为此我们还需要定义一个接口,让生成的类去实现它,以便通过强转的方式获取该值。

/**
 * 约束类,用来获取webview.addJavascriptInterface(obj, name)的name
 * author : pxq
 * date : 19-10-26 上午2:20
 * @see android.webkit.WebView#addJavascriptInterface(Object, String)
 */
public interface IJsBridge {
   
    //获取JavascriptInterface名
    String getName();
}

这里生成的类有点讲究,务必生成在同一个包下,同时加上后缀加以区分,接下来就是javapoet的使用了。类生成之后,最后是绑定到webview上,有了前面的基础,这个就简单了,直接看代码:

	/**
     * 向webview添加处理器,允许多个
     * @param webView
     * @param handlers
     */
    @SuppressLint({
   "SetJavaScriptEnabled"})
    public static void bind(WebView webView, Object..<
  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值