Full solution Android modular communication between the channel module

Thermal paper REVIEW |   Click on the title to read

Under Internet winter, the programmer how to break through to enhance their own?

Mobile APP quality optimization framework - Booster

"37-year-old, 500,000 annual salary, the night was cut": Pseudo work, destroyed many Chinese youth

Author: Pan Chen Xing

Source: Android those things


One, background

Android development, from the initial one-person team, my site I call the shots, with the team and the business gradually become larger, single App developed slowly behind the pace of business development.

  • Code Reusability: then cattle X code to other team can not use, other teams can not be used, nor cattle X.

  • Business Stability: code changes uncontrolled, uncontrollable regression testing, unstable business.

  • Quick launch small satellites: Business To publish a new App, everything from scratch, there is no ready-made components or modules can be shared, Liu Huan sang: big deal all over again?

So it took Android a modular way.


Second, small modular App to App evolution

The modular architecture of the transformation:

640?wx_fmt=png

Architecture architecture early to late

  • App of the original network, picture, UIKIT are put MAVEN warehouse.

  • BaseActivity and public resources to pull away in Common

  • Gradually sinking Business Module, to do service isolation.

When do step 3, we're faced with the selection of the route between the module and the jump. So the selection of the route, Portal: Android Route Selection

After get routing infrastructure can be achieved in the following figure

640?wx_fmt=png

Universal modular architecture

And then it was moved here! And inter-module communication module calls.

In the early pumping module business process, such as product modules used: get the number of shopping cart or add to cart, put these two functions can also sink to the Common, and slowly there is a universal form of Common.

所以面临着模块间的通信和调用的选型,问题如下:三个飘着的气球,要把这几个气球给落地。

640?wx_fmt=png

要落地的气球

  • Big Common :随着模块拆解越来越多,下沉的业务逻辑也会越来越多,大 Common 吾不想要!

  • Muti Module Call: 多模块间调用,不让下沉到Common,那就面临多模块间调用,就要寻找模块间调用的方案。

  • Be On Cloud: 在云端,上云,App上云的概念,第一步是让仓库代码可以被大家依赖调用到。而不是说:哥,你把我这代码拷走吧!把我的BigCommon拷走!(人家才不拷,你在依赖别人库时,多一个功能你都不想要呢)

三、模块间调用思路与方案

640?wx_fmt=png

模块间调用思路


如果是WEB开发,对外声明接口,自己业务去实现接口,再暴露接口去调用具体业务的实现。

如上图所示,购物车模块对外提供两个服务:getCartCount 和 addToCart ,产品页面需要展示当前用户购物车的数量,以及把产品添加到购物车,那产品模块因为依赖了 ServiceCart,可以得到CartService的接口声明定义。

但怎么获取CartService的实例呢?

我相信CartService的实例一定存在世界某个地方,等我去发现。

现在模块化架构就变成如下图:

640?wx_fmt=png

增加Service层

如上图,我们增加了一个Service层,这个Service层虽然画在了Common层上面,但并不依赖Common。

此时,我们要解决的就是 CartService 之我要找到你了!

四、CartService 之我要找到你

如果是服务端开发的话,会把CartService的实现集中注册到 Dubbo 或者 Spring中,通过某个Key得到一个Service的实例。

通过一个Key获得一个实例

前面路由的方案是:通过一个Key获取到一个路径。有点意思。经过比较,ARouter 和 自己通过AIDL来实现两套方案,对比如下:

640?wx_fmt=png

选型标准

ARouter 使用运行时注解强大的功能,自建Map把 path 和 Service具体实例建立关联,跨模块可以轻轻松松地按照自定义路径取出实例调用。一项项来说明:

  • 稳定性:大厂出品,稳定性都OK。

  • 通用技术:第三方注解自建维护Map 和 Android AIDL服务调用,AIDL更通用。

  • 跨进程:ARouter 不支持,而AIDL专为跨进程为生。

  • 易适配:第三方App接入学习成本而言,ARouter还要学习下下,AIDL是Android开发必备技能,不用二次学习。

  • 第三方App调用:系统其他App调用服务定义,ARouter不支持,AIDL 通过Service export= true 的情况下,还是可以支持的。

所以,我们考虑用AIDL Service的方式来实现。

这个时候,你怒了,哥,我裤子都脱了,你就给我看这个?

快 Show Me The Fucking Code!


五、代码秀

有请24位漂亮的女生登场!

640?wx_fmt=png

漂亮女生登场

模块结构如下图:


640?wx_fmt=png

示例代码结构截图

app: 客户端启动入口
module_product : 产品模块
module_shopcart: 购物车模块
service_shopcart: 购物车对外开放服务,通过上面截图可以看到已通过AIDL 声明了 IShopcartService 接口,并声明了 getCartCount 和 addToCart(String productId) 的能力。

看接口的实现如下:

640?wx_fmt=png

AIDL的实现

上面的是不是最AIDL经典实现?还是原来的配方!还是原来的味道!红茶,我只要王老吉?

并在 AndroidManifest.xml 中声明Service如下:

640?wx_fmt=png


同时,注明<intent-filter> 为:com.ssevening.www.service.shopcart.IShopcartService,这个就是查找这个Service的Key,也是IShopcartService 的类路径。在 module_product中的 ProductActivity 中如下方法调用:

640?wx_fmt=png

跨模块调用服务

bindService 和 serviceConnection 还是熟悉的味道,但最上面的Intent 本应该 intent = new Intent(this,ShopcartService.class) , 但ShopcartService类定义在 module_shopcart里面,所以我们新增了:getServiceIntent() 并把类名传递进去,然后通过getPackageManager().queryIntentServices(intent, 0); 查询出action=com.ssevening.www.service.shopcart.IShopcartService 的Service,取第一个封装Intent对象,就可以正常调用AIDL服务了,还是原来的配方,还是原来的味道!

运行截图如下:

640?wx_fmt=png


购物车数量和添加到购物车的结果都已显示出来,同时通过网络调用把 www.baidu.com源码也成功返回。

至此,模块间调用基本方案敲定,余下的就是getServiceIntent() 方法的增强优化和下沉抽到Maven仓库的工作了。

最后,上次路由被坑了一次,详见:Android M queryIntentActivities return null list 蹲坑记 ,用户在App管理界面,可以关掉AppLinks的事,我还记得,所以这次特别去看一下context.getPackageManager().queryIntentServices(intent, 0);

代码截图如下:

640?wx_fmt=png

queryIntentServices,通过看源码,我们发现并没有用户关掉相关的过滤选项,这样我们就放心了。

我们接着说模块间事件传递。比如 登陆状态的变化;在金币频道点击签到按钮,跳转到签到模块签到,签到完成后,回到金币模块签到成功的事情传递。

六、模块间事件传递

事件嘛,那肯定要对比 EventBus 和 广播,对比如下:

640?wx_fmt=png

EventBus 和 广播对比

这样一对比,不用接第三方库就能实现,并且是Android通用方案,后期第三方接入和使用都方便,所以模块间事件传递就用:BroadcastReceiver,这个连例子都不用写了。大家都懂的。

更多学习和讨论,欢迎加入我们的知识星球,这里有1000+小伙伴,让你的学习不寂寞~·

看完本文有收获?请转发分享给更多人


我们的知识星球第三期开期了,已达到1100人了,能连续做三期已很不容易了,有很多老用户续期,目前续期率达到50%,说明了大家对我们的知识星球还是很认可的,欢迎大家加入尽早我们的知识星球,更多星球信息参见:

欢迎加入Java和Android架构社群

如何进阶成为Java的Android版和架构师?

说两件事

640?wx_fmt=jpeg

微信扫描或者点击上方二维码领取的Android \ Python的\ AI \的Java等高级进阶资源

Click below to learn more information , "read the original  " Get

640?wx_fmt=gif

Thank you, boss, good-looking point ↓

Guess you like

Origin blog.csdn.net/xJ032w2j4cCjhOW8s8/article/details/91470958