APP路由还能这样玩
本文主要讲述一种设计思路,组件化架构市面上已经有很多大厂成熟的方案,但是在组件化过程中,偶尔会遇到2个独立业务子模块间没有相互引用,也需要能直接调用对方的功能,因此我想到通过方法路由来解决,如果还有疑问,可以发邮件到我的邮箱ufolca@163.com或者加我微信号【the51alien】备注一下“简书”,如有不妥之处,还请指正
起源
一次跨部门合作开发APP时遇到一个问题,我们各自开发几个业务组件,A部门有个功能需要直接调用我这边的功能,如果只是打开我这边的界面,可以通过界面路由唤起,这时很容易想到了2种实现
把这个功能抽取到业务组件的基类base组件里
把这个功能代码copy一份到A部门的组件里
这2种方案一种是会让基类组件涉及到业务,另一种如果该业务功能后期有修改得把所有组件里copy这块代码的都要改一次,均不是完美的解决方案
启发
联想到页面路由方案,既然页面我可以通过url来调用,方法为什么不可以呢,那我就试试通过代理的模式来实现
base模块IMethodBaseProxy.java
public interface IMethodBaseProxy {
/**
* @param modelTag 模块别名
* @param methodName 方法名
* @param params 方法参数数组
* @return true 当前代理类方法支持该方法并且执行 ;false 当前代理类里不支持该方法名和参数
*/
boolean envoke(String modelTag, String methodName, Object[] params);
/**
* @return 返回代理模块名
*/
String getTag();
}
复制代码
base模块ModelProxyManager.java-用来管理和执行所有业务模块的方法代理
public class ModelProxyManager {
private HashMap<String, IMethodBaseProxy> methodProxyMap = new HashMap<>();
public static class ModelProxyManagerHolder {
public static ModelProxyManager instance = new ModelProxyManager();
}
public static ModelProxyManager getInstance() {
return ModelProxyManagerHolder.instance;
}
private ModelProxyManager() {
}
public void addMethodProxy(IMethodBaseProxy proxy) {
if (methodProxyMap != null) {
methodProxyMap.put(proxy.getTag(), proxy);
}
}
/**
* 遍历寻找对应的方法所在的代理类并且进行调用
*
* @param modelTag 模块别名
* @param methodName 方法名
* @param paras 方法参数
* @return
*/
public boolean envoke(String modelTag, String methodName, Object[] paras) {
if (methodProxyMap != null && methodProxyMap.containsKey(modelTag)) {
IMethodBaseProxy methodProxy = methodProxyMap.get(modelTag);
if (methodProxy.envoke(modelTag, methodName, paras)) {
return true;
}
}
return false;
}
}
复制代码
a模块AMethodProxy.java-将a模块的业务功能通过方法代理暴露出来
public class AMethodProxy implements IMethodBaseProxy {
@Override
public boolean envoke(String modelTag, String methodName, Object[] params) {
if ("test".equals(methodName)) {
test();
return true;
} else if ("testContext".equals(methodName)) {
if (params != null && params.length == 1) {
try {
testContext((Context) params[0]);
return true;
} catch (Exception e) {
}
}
} else if ("testCallback".equals(methodName)) {
if (params != null && params.length == 3) {
try {
testCallback((Context) params[0], params[1].toString(), (MethoProxyCallBack) params[2]);
return true;
} catch (Exception e) {
}
}
}
return false;
}
private void testCallback(Context ctx, String s, MethoProxyCallBack callBack) {
if (callBack != null) {
callBack.callBack("{\"" + s + "\":\"success\"}");
}
}
private void testContext(Context ctx) {
Toast.makeText(ctx, "moudle-a.testContext()", Toast.LENGTH_SHORT).show();
}
private void test() {
Log.d("moudle-a.test()", "success");
}
@Override
public String getTag() {
return "a";
}
}
复制代码
b模块BTest.java-用来调用a模块的业务方法
public class BTest {
public void test() {
ModelProxyManager.getInstance().envoke("a", "test", null);
}
public void testContext(Context context) {
ModelProxyManager.getInstance().envoke("a", "testContext", new Object[]{context});
}
public void testCallback(Context context, String s, MethoProxyCallBack callBack) {
ModelProxyManager.getInstance().envoke("a", "testCallback", new Object[]{context, s, callBack});
}
}
复制代码
app模块MainActivity.java-用来测试跨组件方法调用
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//模块A的方法代理添加到总的方法代理中心
ModelProxyManager.getInstance().addMethodProxy(new AMethodProxy());
final BTest bTest = new BTest();
findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
bTest.test();
}
});
findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
bTest.testContext(MainActivity.this);
}
});
findViewById(R.id.btn3).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
bTest.testCallback(MainActivity.this, "bbb", new MethoProxyCallBack() {
@Override
public void callBack(String jsonStr) {
Toast.makeText(MainActivity.this, "moudle-a.testCallback()===para:" + jsonStr, Toast.LENGTH_SHORT).show();
}
});
}
});
}
}
复制代码
传送门
APP路由还能这样玩的更多相关文章
- 呛口大话APP 移动端到底怎么玩
[上海站]活动概况 时间:2016年04月09日13:30-16:30 地点:上海市黄浦区黄陂北路227号中区广场105室WE+联合办公空间 主办:APICloud.七牛.听云 报名网址:http:/ ...
- Java 11 已发布,String 还能这样玩!
在文章<Java 11 正式发布,这 8 个逆天新特性教你写出更牛逼的代码>中,我有介绍到 Java 11 的八个新特性,其中关于 String 加强部分,我觉得有点意思,这里单独再拉出来 ...
- Android事件总线还能怎么玩?
作者简介:何红辉,Android工程师,现任职于友盟. 顾名思义,AndroidEventBus是一个Android平台的事件总线框架,它简化了Activity.Fragment.Service等组件 ...
- Java 12 骚操作, String居然还能这样玩!
Java 13 都快要来了,12必须跟栈长学起! Java 13 即将发布,新特性必须抢先看! 栈长之前在Java技术栈微信公众号分享过<Java 11 已发布,String 还能这样玩!> ...
- tornado实现不同app路由分发
tornado实现app路由分发 from tornado import ioloop from tornado.httpserver import HTTPServer from tornado.w ...
- Apache DolphinScheduler 需要的sudo,还可以这么玩,长见识了!
Apache DolphinScheduler(incubator)需要的sudo,还可以这么玩,长见识了! 在新一代大数据任务调度 - Apache DolphinScheduler(以下简称dol ...
- Word揭秘:公式还能这么玩!
如今办公室里用Word来处理资料文档一种再普遍不过的现象了,学校的老师出试卷也离不开它.用Word编辑公式也是一个非常的技巧,玩转Word的同时,你玩转公式了吗?想要在Word中编辑公式,可不是说说就 ...
- Docker竟然还能这么玩?商业级4G代理搭建实战!
时间过得真快,距离这个系列的上一篇文章<商业级4G代理搭建指南[准备篇]>发布的时间已经过了两个星期了,上个星期由于各种琐事缠身,周二开始就没空写文章了,所以就咕咕咕了. 那么在准备篇中, ...
- 继 “多闪”后“飞聊”再被diss?其实社交还能这么玩
近日头条低调上线了新的社交APP——飞聊,目前在AppStore社交排行榜第7位.但很多人使用了之后都觉得新产品的各个功能都让人想起其他的产品.兴趣小组让人想到豆瓣的兴趣小组,生活动态让人想到微博动态 ...
随机推荐
- 使用tap、Fragment等相关相关知识点。实现类似微信的界面
实验结果,可以实现通过左右活动来切换不同的界面.也可以通过点击不同的下方按钮来实现切换不同的界面. 自己也添加了相关的自己编写的小页面来展示相关的效果.主要的是对于碎片Fragment对于tap的相关 ...
- MTK Android 回调机制[CallBack]
具体步骤: 一.建模 回调函数的关键是:将一段代码作为参数传递,而这段代码将会在某个时刻被执行 我理解的接口回调就是,我这个类实现了一个接口里的方法doSomething,然后注册到你这里,然后我就去 ...
- 答好友困惑:Java零基础如何入门,不知道怎么学,迷茫ING
作者:程序员小跃 几个星期之前,我在知乎上看到一个提问,说是:对于完全没有经验零基础自身的数学底子也很弱学习Java应该怎么学习呢?想着类似的问题我也有过回答,并且反馈还是蛮好的,就参考之前的思路回答 ...
- python3(二十七)property
""" """ __author__ = 'shaozhiqi' # 绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单, # 但是, ...
- windows上jmeter目录结构功能
1.bin :存储了jmeter的可执行程序,如启动 2.lib:存储了jmeter的整合的功能(如.jar文件程序) 3.启动jmeter:双击bin\apachejmeter.jar jmeter ...
- Powershell操作MySQL
最近再用Python写一些监控脚本,并将监控数据输出到MySQL中,最后通过Python抓取MySQL中的数据进行监控汇总告警 考虑到一些微软产品使用Powershell更为方便,于是找了些资料,尝试 ...
- 007-函数-C语言笔记
007-函数-C语言笔记 学习目标 1.[了解]函数的分类 2.[掌握]函数的声明定义和调用 3.[掌握]函数的形参和实参 4.[掌握]带返回值的函数 5.[掌握]全局变量和局部变量 6.[了解]注释 ...
- Web 如何搭建自己的个人网站
如何搭建自己的个人技术博客网站 学习目标 1.[了解]搭建网站需要的web构件和网站运行原理 2.[掌握]如何搭建个人博客网站 学习前言 大家都是学习开发的,相信都接触过百度,新浪,淘宝,京东...等 ...
- 09-sass
一.sass和scss sass最初是为了配合haml设计的,不需要大括号,用tab缩进 从第三代开始,保留缩进风格,完全向下兼容普通的css代码 二.下载配置sass compass是sass的一个 ...
- Linux下安装Redis4.0版本(简便方法)
Redis介绍: Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久 ...