Magic-Hybrid 混合开发架构原理解析
题外话。本来年初的时候决定今年上半年写很多篇帖子的,然而后来项目比较忙,我又忙着考试,总之一些其它意料之外的事情,很多,不得不中断了。今天趁有一点时间,赶紧把项目里使用的混合开发架构Magic-Hybrid总结出来。写的不好,有错误或者建议还请不吝赐教,非常感谢
1. 两个端
1.Web:不管是JS、H5、网页前端,我们统称为Web;
2.Native:不管是Android、IOS、app、还是移动端,我们统称为Native。
2. 两个方向 —— 一个核心
我们将Web <——> Native之间的交互拆分为两个方向:Web to Native,Native to Web。然而不论是那种,其核心思想都是消息的传递,我认为都应该细分为以下几个步骤:
- 1.产生事件:将事件类型和必要参数信息组合产生一个事件;
- 2.转化消息:将事件转化为可以传递的消息;
- 3.传递消息:将消息从一端传递到另一端;
- 4.分析事件:接收端将消息转化为可以执行的事件;
- 5.执行事件:接收端根据事件类型和必要的参数信息执行事件。
3. 两个方法
可以看出来,不论是哪一端到哪一端,交互核心都是消息的传递。因此,我认为在Hybrid交互过程中,
交互方式的重点应该是消息的传递和事件的类型,而不是方法;
另一方面,Web和Native两端应该避免
过多的耦合,以适应需求的快速变更和迭代,因此两端应该对彼此知道的越少越好,最终彼此只需要暴露一个方法供对方调用来传递消息。因此,最终只需要一个方法:
- 1.String nativeExecute(String jsMsg):Native需要实现的方法,Web给Native传递消息时调用的方法;
- 2.webExecute(String nativeMsg):Web需要实现的方法,Native给Web传递消息时调用的方法;
4. 两个事件
由上述第二条可知,交互分为两部分,二者对应的事件为:
- NativeEvent——Web to Native;
- WebEvent——Native to Web 。
接下来介绍详情:
4.1. NativeEvent:web请求netive执行的事件
我们将web主动与native通信并传递给Native的包含 请求native执行的事件的类型和执行该项事件必要的信息这两项内容合并抽象为一个事件-NativeEvent;
NativeEvent担负一个责任,就是需要将Web传递给Native的数据-jsMsg,翻译成一个事件,其中必须准确的翻译出请求执行的事件的类型-OPERATION_TYPE,以及事件必要的参数-params(params的格式很随意,可以是我们任何已有的类型)以便在BaseNativeEventHandler执行的时候能够直接的拿到有效的数据;
public final class NativeEvent {
//事件类型
private String OPERATION_TYPE = null;
//必要的参数信息
private String params = null;
/**
* jsMsg 格式
* {
* "OPERATION_TYPE": "REQUEST_ENCRYPT",//操作符
* "params": {
* "phone": "13512345678",
* "password": "qwer1234"
* ...
* }
*
}
*/
/**
* 在这个构造函数中,我们将Web传递给Native消息体转化为包含操作符和关键参数字段的一个<strong>事件</strong>
*
* @param jsMsg Stirng:Web传递给Native消息体
*/
public NativeEvent(@NonNull String jsMsg) {
if (jsMsg != null && jsMsg.length() > 0) {
try {
JSONObject eventJsonObject = new JSONObject(jsMsg);
//1.得到requestOperationType
final String OPERATION_TYPE = HybridAgreementEnum.OPERATION_TYPE.name();
if (jsMsg.contains(OPERATION_TYPE)) {
this.OPERATION_TYPE = eventJsonObject.getString(OPERATION_TYPE);
}
//2.得到params
final String PARAMS = HybridAgreementEnum.params.name();
if (jsMsg.contains(PARAMS)) {
params = eventJsonObject.getString(PARAMS);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
/**
* 在一些特殊的情况下,我们可能会需要自己创造一个web事件
*
* @param requestOperationType String :必须是大写的操作符
* @param params json格式的参数
*/
public NativeEvent(@NonNull String requestOperationType, @NonNull String params) {
this.OPERATION_TYPE = requestOperationType;
this.params = params;
}
/**
* 当前事件的 操作符
*
* @return
*/
public final String getRequestOperationType() {
return OPERATION_TYPE;
}
/**
* 当前事件的参数
*
* @return
*/
public String getParams() {
return params;
}
@Override
public String toString() {
return new Gson().toJson(this);
}
}
4.2. WebEvent,native主动请求web执行的事件。
同NativeEvent,我们将Native主动与Web通信并传递给Web的包含请求Web执行的事件的类型以及执行该事件必要的信息这两项内容合并
抽象为一个事件-WebEvent;
/**
* Created by : mr.lu
* Created at : 2019-05-24 at 10:09
* Description:
*/
public class WebEvent<T> {
/**
* 操作符-事件类型
*/
private String OPERATION_TYPE;
/**
* 需要给Web传递的参数
*/
private T params;
public WebEvent(Enum OPERATION_TYPE, T params) {
this.OPERATION_TYPE = OPERATION_TYPE.name();
this.params = params;
}
public WebEvent(Enum OPERATION_TYPE) {
this.OPERATION_TYPE = OPERATION_TYPE.name();
}
public final String getOperationType() {
return OPERATION_TYPE;
}
@Override
public String toString() {
return new Gson().toJson(this);
}
}
5. 两个事件的执行者 – IEventHandler
同上述-3-,事件执行的重点应该是消息的事件的类型和必要,而不是方法;
因此,最终只需要一个方法:
public interface IEventHandler {
String execute(BaseWebViewFragment fragment, String params);
}
5.1. BaseNativeEventHandler,NativeEvent 的执行者。
此情此景,感觉适合用责任链模式,于是就用责任链模式吧
public class NativeEventManager {
private final Map<String, BaseNativeEventHandler> EVENT_HANDLER_MAP = new HashMap<>(1);
private final String EVENT_HANDLER = "EVENT_HANDLER";
private EventManager() {
}
private static class Holder {
private static final NativeEventManager INSTANCE = new NativeEventManager();
}
public static NativeEventManager getInstance() {
return Holder.INSTANCE;
}
/**
* 添加Hybrid事件处理者;<br>
* <p>我们的EventManger是一个喜新厌旧却不贪心的管理器:可以放心的是,尽管调用当前方法的时候,我们对
* BaseNativeEventHandler{@link BaseNativeEventHandler}
* 创造新的实例并没有做限制,这意味着前后可能有多个相同EventHandler的实例会被传递过来,但是我们的内心始终
* 只有一个位置,尽管来来往往的handler不断,我们内心只允许一个handler停留--后来的取代早先来的。
* <p>
*
* @param eventHandler BaseHybridEventHandler的子类实例。
* @return
*/
pu

最低0.47元/天 解锁文章
943

被折叠的 条评论
为什么被折叠?



