现代Android应用追求快速迭代,快速迭代的终极形态就是动态化,现在动态化比较好的就有Hybird,免不了Native与H5进行交互,常用的方案有JsBridge,或者直接使用原生提供的方法,这篇文章就是提供处理从原生方案迁移到类似JsBridge方案的一个思路。
背景
现存的老项目,或者项目不太老,但是最初定协议的时候直接使用了系统提供方案,没有进行包装,随着项目的演进,需求变得复杂,方法数变得更多,原来的方案慢慢变得不太合适,可能有下面一些原因:
- 无法对方法提供权限校验(其实可以通过AOP进行控制)
- 代码都要写到一个类里来,最终这个类会非常庞大,有很多相与不相关的方法,内聚性不强
- 如果打开了外部页面,js可以对Native提供的方法进行穷举,有一定风险
为了我们代码写得爽和绝后患,想要将原来的方案迁移到类似JsBridge的方案上来。那么问题就来了,已经有很多存量的网页在使用原来的协议,怎么才能对前端同学兼容原来的方案
方案
前端描述了那么多,其实解决方案并不复杂。
我们知道,通过系统提供的方法addJavascriptInterface(Object obj, String interfaceName),在前端的window上注册一个对应的对象,名称就是方法中的interfaceName,协议中的方法对应到interfaceName对象上的每一个方法。
直接使用原来的方案,会有在注入前端对象上有多个方法
@JavascriptInterface
public void method(String jsonParam) {
doMethod(jsonParam);
}
@JavascriptInterface
public void action(String jsonParam) {
doAction();
}
@JavascriptInterface
public void moreParamsMethod(String jsonParam, String callback) {
doMoreParamsMethod(jsonParam, callback);
}
举例,前两个方法名不一样,但是参数都使用了json的形式,大多数应该使用这种形式
第三个方法更野一些,不同的方法参数的数量和类型都不一样。
使用JsBridge方案注入前端对象(bridge)上只有一个方法,
public void callNative(final String action,
final @Nullable String params,
final @Nullable String callback) {
}
我们想在native上使用JsBridge方案,把不现的业务写在不同的类中,同时又不影响已有的前端页面。其实我们要做的就是构造一个适配器,将原来的调用转到新形式的调用上来。 为了不影响已经上线的前端页面,适配器一定要在native做。方法基本上就确定了,native来构造这个适配器对象并挂到window上。
方法
构造一段JS在前端执行
if (!window.interfaceName) {
window.interfaceName = {
method: function (jsonParam) {
window.bridge.callNative('method', jsonParam);
},
action: function (jsonParam) {
window.bridge.callNative('action', jsonParam);
},
moreParamsMethod: function (message, callback) {
window.bridge.callNative('moreParamsMethod', message, callback);
},
};
}
可以通过Stringbuilder,使用字符模板将每一个方法拼接上来。
如果更复杂的参数类型,可能要在适配器中写JS代码将原来的json合成一个符合callNative的参数。
总结
与前端有关的时候,不要把自己局限在native,可以学习一些前端知识,或者与前端同学一同找问题的解决方案。