Android模块化中数据传递/路由跳转实现示例
作者:左手木亽 发布时间:2023-06-29 03:12:06
虽然说模块通信、路由协议在Android已经不新鲜了,但是如果脱离了那些优秀的开源库我们从零开始自己造一个库,有时候重复造轮子会让自己对所谓"车"的原理懂得更透彻。
直接上造完的轮子地址: https://github.com/Neacy/NeacyComponent
这个轮子有两个大功能分别是模块通信以及路由跳转:
模块通信
首先,统一声明姿势:
public interface IComponent {
String getName();
void startComponent(ComponentParam param);
}
也就是说,在各自的维护的模块内若想提供一个类供别的模块调用那么需要实现这个 IComponent 类,这样子可以根据面向对象的优势统一管理,所以我们就有了接下来的这么一个个Component类,比如:
@NeacyComponent("app")
public class AppComponent implements IComponent {
@Override
public String getName() {
return "app";
}
@Override
public void startComponent(ComponentParam param) {
Log.w("Jayuchou", "==== Start AppComponent ====");
if (param != null && param.getParam().containsKey("callback")) {
ICallBack callBack = (ICallBack) param.getParam().get("callback");
Map<String, Object> results = new HashMap<>();
results.put("result", "我来自AppComponent");
ComponentParam cp = new ComponentParam(results);
callBack.onComponentBack(cp);
}
}
}
两个地方比较重要:
NeacyComponent 这个注释,主要是为后面的gradle扫描使用
getName() 这个方法返回每个 IComponent 对应的实例key值,方便在不同的模块我们可以根据这个key值找到对应的 IComponent 对象
其次,如何调用呢?
ComponentController.getComponentByName("app").startComponent(null);
是的,只要根据app这个key值我们就能轻易的找到对应的 IComponent 对象,从而执行 startComponent ,这个方法就是你想要在该模块做的逻辑地方。
看上面我们声明的 AppComponent 类,我们在 startComponent 有判断一下传入的参数是否为空,这里直接放了一个伪 Map 类专门用于存放传递的参数。
如何回调结果以及如何获取别的模块的回调结果?
首先你执行了别的模块的 startComponent 方法,在这个方法中你返回的类肯定只有对应的模块能识别,也就是说你在自己模块获取不到别的模块中的类,所以这里使用 ComponentParam 采用key/value的风格存放参数以及回调返回结果,然后看一下下面的代码就能明白答案了。
// 传递参数给IComponent, 可以通过传递回调函数从而得到回调结果
Map<String, Object> p = new HashMap<>();
p.put("callback", new ICallBack() {
@Override
public void onComponentBack(ComponentParam result) {
Log.w("Jayuchou", "==== 运行结果 = " + result.getParam().get("result"));
}
});
ComponentParam cp = new ComponentParam(p);
// 回调结果回去
ICallBack callBack = (ICallBack) param.getParam().get("callback");
Map<String, Object> results = new HashMap<>();
results.put("result", "我来自AppComponent");
ComponentParam cp = new ComponentParam(results);
callBack.onComponentBack(cp);
// 调用的时候传入参数即可
ComponentController.getComponentByName("app").startComponent(cp);
路由跳转
首先,老规矩肯定也是声明一下路由协议(这里只是一个简单的字符串)
@NeacyProtocol("/activity/a")
public class AActivity extends AppCompatActivity
@NeacyProtocol("/activity/b")
public class BActivity extends AppCompatActivity
@NeacyProtocol("/activity/app")
public class MainActivity extends AppCompatActivity
然后调用就是了:
RouterController.startRouter(MainActivity.this, "/activity/a");// 跳转到AActivity
Bundle args = new Bundle();
args.putString("key", "AActivity");
RouterController.startRouter(AActivity.this, "/activity/b", args);// 跳转到BActivity并携带bundle参数
原理
原理就是通过gradle插件结合ASM扫描注解并在编译的时候注入代码,我们先看 * 入成功后的代码结构:
1.模块通信的注入结果
public class ComponentController
{
static
{
registerComponent(new AComponent());
registerComponent(new BComponent());
registerComponent(new AppComponent());
}
private static Map<String, IComponent> components = new HashMap();
static void registerComponent(IComponent component)
{
components.put(component.getName(), component);
}
.
.
.
}
2.路由跳转注入结果
public class RouterController
{
static
{
addRouter("/activity/a", "com.neacy.neacy_a.AActivity");
addRouter("/activity/b", "com.neacy.neacy_b.BActivity");
addRouter("/activity/app", "com.neacy.component.MainActivity");
}
private static Map<String, String> routers = new HashMap();
public static void addRouter(String key, String value)
{
routers.put(key, value);
}
}
3.更多gradle插件的代码查阅 https://github.com/Neacy/NeacyComponent
最后
再次感谢灵感: https://github.com/luckybilly/CC
来源:https://www.jianshu.com/p/e5fdacdd4488
猜你喜欢
- SpringCloud Function 介绍SpringCloud 是一套分布式系统的解决方案,常见的还有阿里巴巴的Dubbo,Fass(
- public class Deskew { &
- 在开发应用过程中,客户端与服务端经常需要进行数据传输,涉及到重要隐私信息时,开发者自然会想到对其进行加密,即使传输过程中被“有心人”截取,也
- 代码从windows下visual studio到andriod平台迁移实现步骤:前言前言也是迁言,从windows的visual stud
- 1、获取表中最后一条数据public static String demo() throws SQLException { String s
- 为什么要使用路由在之前我们的代码中,页面跳转使用的代码如下所示:Navigator.of(context).push( Mate
- Condition的作用是对锁进行更精确的控制。Condition中的await()方法相当于Object的wait()方法,Conditi
- 第一步、效果展示图1、蓝色的进度条 图2、红色的进度条 图3、多条颜色不同的进度条 图4、多条颜色不同的进度条第二步、自定义Progress
- java类型转换 Integer String Long Float Double Date1如何将字串 String 转换成整数 int?
- 什么是死锁我们先看看这样一个生活中的例子:在一条河上有一座桥,桥面较窄,只能容纳一辆汽车通过,无法让两辆汽车并行。如果有两辆汽车A和B分别由
- 一、 lib文件的简介.lib是一种文件后缀,是Windows操作系统的库文件,有静态lib和动态lib之分:1)、静态lib文件
- 一、常见问题所有的final修饰的字段都是编译期常量吗?如何理解private所修饰的方法是隐式的final?说说final类型的类如何拓展
- 为了防止测试妹子或者用户频繁点击某个按钮,导致程序在短时间内进行多次数据提交or数据处理,那到时候就比较坑了~那么如何有效避免这种情况的发生
- 冒泡排序冒泡排序的思想:每次让当前的元素和它的下一个元素比较大小、如果前一个的元素大于后一个元素的话,交换两个元素。这样的话经历一次扫描之后
- 公司运维问我怎么在windows上安装模拟器,我你说你安装模拟器干什么?他说,我安装模拟器查看app的包名这些信息做统计。我顿时想,有必要这
- 定时任务,是指定一个未来的时间范围执行一定任务的功能。在当前WEB应用中,多数应用都具备任务调度功能,针对不同的语音,不同的操作系统, 都有
- 题目要求阅读理解读完题的我be like:去看了遍英文版就懂了,题目中的种类【type】不是种类数…&hell
- 什么是JavaMemoryModel(JMM)?JMM通过构建一个统一的内存模型来屏蔽掉不同硬件平台和不同操作系统之间的差异,让Java开发
- Java 判断字符串是否为IP地址,供大家参考,具体内容如下1、代码主要就是这么几个条件非空长度符合 0.0.0.0 - 255.255.2
- 废话不多说,直接上代码/// <summary> /// 获得当前绝对路径