android rn框架开发的例子,RN与安卓通信架构篇
本篇文章介绍的搭建Android与Rn之间的简易通信架构,需要了解通信的基本使用的同学可以参考下面的链接开篇先上图 - “简易版的通信架构图”RN与Android之间通信的架构图本架构实现的功能有:自定义通信规则,并以Json作为数据传输格式进行传输实现通信场景分两种: 1) RN主动向Android获取数据 2)Android主动向RN传输数据先着重介绍场景1(RN主动向Android获取数据)
本篇文章介绍的搭建Android与Rn之间的简易通信架构,需要了解通信的基本使用的同学可以参考下面的链接
开篇先上图 - “简易版的通信架构图”
RN与Android之间通信的架构图
本架构实现的功能有:
自定义通信规则,并以Json作为数据传输格式进行传输
实现通信场景分两种: 1) RN主动向Android获取数据 2)Android主动向RN传输数据
先着重介绍场景1(RN主动向Android获取数据),进行数据传输的格式
协议:rn://xxxmodule?funTarget=main_cache
协议的Schema:‘rn://’标识为此通信的标识,可验证通信正确性
协议的Host:‘xxxmodule’此标识为传递给对应的业务模块执行。包括:网络加载模块,本地数据缓存模块等等。
协议的queryParams: ‘funTarget’ 这个key用于标识模块需要执行的动作。比如网络模块需要拉取个人信息,需要拉取首页信息,此标识用于执行动作的区分
如下例子:
rn://networkmodule?funTarget=person_info, 到网络模块中拉取个人信息
rn://networkmodule?funTarget=main_page, 到网络模块中拉取首页信息
以上协议贯穿了整个架构的设计,下面介绍代码实现部分
协议规则实现类BridgeUrlConfig, BridgeUrlConst
public interface BridgeUrlConst {
String RN_SCHEMA = "rn";
String RN_NETWORK_MODULE = "network";
String COMPLETE_RN_SCHEMA = RN_SCHEMA + "://";
}
public enum BridgeUrlConfig {
//target: 网络模块
NETWORK_MODULE(BridgeUrlConst.COMPLETE_RN_SCHEMA + BridgeUrlConst.RN_NETWORK_MODULE),
//action: 网络模块下执行main_cache动作
NETWORK_SYNC_MAIN_CACHE(NETWORK_MODULE, "main_cache"),
//action: 网络模块下执行second_cache动作
NETWORK_SYNC_SECOND_CACHE(NETWORK_MODULE, "second_cache"),
//action: 网络模块下执行request动作
NETWORK_ASYNC_REQUEST(NETWORK_MODULE, "request");
private String target;
private BridgeUrlConfig parentConfig;
BridgeUrlConfig(String target) {
this.target = target;
this.parentConfig = null;
}
BridgeUrlConfig(BridgeUrlConfig parentConfig, String target) {
this.target = target;
this.parentConfig = parentConfig;
}
public String getTarget() {
return target;
}
public BridgeUrlConfig getParentConfig() {
return parentConfig;
}
}
以上使用接口常量与枚举实现规则定义, 更直观的方便我们后面的解析解析和判断的使用
如何使用协议?RN与原生通信入口 BridgeUrlAnalysis
//用来声明模块
public interface IModuleExecuteEntry {
/*
* funTarget: 需要执行的action
* argJson: 执行此action需要的参数
* promise: 用于执行结果的回调,可查看官网文档,上方链接有说
* 明。注意异步或同步兼用回调返回。
*/
void execute(String funTarget, String argJson, Promise promise);
}
//通信协议执行入口类
public class BridgeUrlAnalysis {
private static BridgeUrlAnalysis bridgeUrlAnalysis = new BridgeUrlAnalysis();
private BridgeUrlAnalysis() {
}
public static BridgeUrlAnalysis getInstance() {
return bridgeUrlAnalysis;
}
final Map modules = new HashMap<>();
//1.注册可执行模块
{
modules.put(URI.create(BridgeUrlConfig.NETWORK_MODULE.getTarget()).getHost(), new NetworkModule());
}
/**
* //2.通信入口方法
* 正确的url格式:‘ react_native://xxxmodule?funTarget='main_cache' "
*
* @param url
* @param argsJson
*/
public void analysis(String url, String argsJson, Promise promise) {
if (TextUtils.isEmpty(url)) {
throw new RuntimeException("please url not empty");
}
URI uri = URI.create(url);
if (!uri.getScheme().equals(BridgeUrlConst.RN_SCHEMA)) {
throw new RuntimeException("please url not correct");
}
//根据url中的host获取对应注册的module
String host = uri.getHost();
IModuleExecuteEntry entry = modules.get(host);
if (entry == null) {
throw new RuntimeException("this target module not init");
}
//解析url中的query,获取name为“funTarget”的值
String paramString = uri.getQuery().split("#")[0];
Matcher matcher = Pattern.compile("(^|&)" + "funTarget=" + "([^&]*)").matcher(paramString);
matcher.lookingAt();
entry.execute(matcher.group(2), argsJson, promise);
}
}
以上类需要注意两点:
1.注册可执行协议的模块
2.通信协议的入口执行逻辑
然后介绍场景2,Android主动发送数据给RN
此处使用了事件发送技术,类似EventBus的用法。
因为比较简单就直接上Android代码
/**
* 1.原生模块可以在没有被调用的情况下往 JavaScript 发送事件通知
*/
public interface INativeSendToRnBridge {
/**
* 发送事件到RN上
* @param eventName 设置发送事件的名称,RN可对此名称的事件进行监听
* @param jsonObj
*/
void sendEvent(String eventName, String jsonObj);
}
/**
*具体实现类
*/
public class AndroidSendToRNBridge implements INativeSendToRnBridge {
private ReactContext mReactContext;
public AndroidSendToRNBridge(ReactContext context) {
this.mReactContext = context;
}
/**
* 发送数据的入口,规定了发送事件的格式
* eventName: 用于区分事件,相当于key
* jsonObj: 事件所包含的数据,相当于value。建议以Json格式数
* 据发送
*/
@Override
public void sendEvent(String eventName, String jsonObj) {
mReactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, jsonObj);
}
public ReactContext getReactContext() {
return mReactContext;
}
public void setReactContext(ReactContext mReactContext) {
this.mReactContext = mReactContext;
}
}
本篇文章介绍完毕啦,需要源码的小伙伴可私信我。
更多推荐
所有评论(0)