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位.但很多人使用了之后都觉得新产品的各个功能都让人想起其他的产品.兴趣小组让人想到豆瓣的兴趣小组,生活动态让人想到微博动态 ...
随机推荐
- GlusterFS 4.1 版本选择和部署
GlusterFS 4.1 版本选择和部署 目录 GlusterFS 4.1 版本选择和部署 1 前言相关 1.1 glusterfs优势 1.2 版本选择 1.3 volume知识 2 服务部署 2 ...
- 在tap的碎片上与活动进行绑定实现点击事件(日期时间选择以及按钮跳转时间)
主要是掌握怎样在Fragment类型的.java文件中实现对于文本框或者按钮点击事件的触发操作. 相应的出发时间都是之前的代码.主要是怎样在Fragment怎样实现相应的操作主要是对于getActiv ...
- flask-文件上传的使用
flask-文件上传 在flask中使用request.files.get来获取文件对象 对获取到的文件对象可以使用save(filepath)方法来保存文件 上传的文件在保存前需要对文件名做一个过滤 ...
- 2017蓝桥杯最大公共子串(C++B组)
题目: 最大公共子串长度问题就是:求两个串的所有子串中能够匹配上的最大长度是多少.比如:"abcdkkk" 和 "baabcdadabc",可以找到的最长的公共 ...
- PHP中嵌入正则表达式常用的函数
PHP中嵌入正则表达式常用的函数有四个: 1.preg_match() :preg_match() 函数用于进行正则表达式匹配,成功返回 1 ,否则返回 0 . 语法:int preg_match( ...
- C语言实现顺序表(顺序存储结构)
顺序表(顺序存储结构)及初始化过程详解 顺序表,全名顺序存储结构,是线性表的一种.通过<线性表>一节的学习我们知道,线性表用于存储逻辑关系为"一对一"的数据,顺序表自然 ...
- 条件变量 condition_variable wait_until
wait_until(阻塞当前线程,直到条件变量被唤醒,或直到抵达指定时间点) #include <iostream> #include <atomic> #include & ...
- 如何利用 githob 上传自己的网站
如何搭建自己的网页是每个学前端伙伴不可缺少的一个过程,特意去看过很多如何搭建的教程,但都看不懂觉得很麻烦, 在慢慢的学习中接触到githob,发现了一个大宝藏(如果一个code都不认识githob 那 ...
- iOS技能 - 最新美团、百度、腾讯、头条、阿里 面试题目记录
关于面试题,可能没那么多时间来总结答案,有什么需要讨论的地方欢迎大家指教.主要记录一下准备过程,和面试的一些总结,希望能帮助到正在面试或者将要面试的同学吧. 美团 一面 1.简历上写的项目问了一遍,然 ...
- VulnHub靶场学习_HA: ARMOUR
HA: ARMOUR Vulnhub靶场 下载地址:https://www.vulnhub.com/entry/ha-armour,370/ 背景: Klaw从“复仇者联盟”超级秘密基地偷走了一些盔甲 ...