如果我们要为某个已经存在的组件,重新开发一个新组件,将变得非常可行。

组件内的重构也将变得非常可行。

新的组件的设计只要保证对外提供的接口,完全符合,旧组件对外提供的接口

5、组件的热插拔,成为可能(如果构建正确

我们想象下,在APP运行时,business中的组件可以动态加载,也可动态卸载。

那么我们可以轻松实现组件的懒加载:用户用到的组件,那么就加载进来。用完之后便可以卸载。

6、组件的独立编译、测试,成为可能(如果构建正确

大的android工程项目,build一次要到5分钟左右,太浪费时间了。

拆成多个组件之后,如果每个组件都能单独build,单独测试,那么将大大提升开发效率。

上面讨论的这些优势,并不是将简单将 单工程 拆分成 分层的多module工程结构 就能获得这些优势。

想要获得这些优势,还任重道远,我们还需要解决很多问题,才能让我们的项目具备上面的说的优势。

二、组件化后,将面临哪些问题?如何解决?

1、module之间如何优雅的通信

通过ARouter通信。

ARouter是阿里开源的一个项目。github.com/alibaba/ARo…

通过ARouter跨module跳转Activity

@Route(path = “/test/activity”)//申明路由

public class YourActivity extend Activity {

}

//通过路由启动Activity

ARouter.getInstance().build("/test/activity").withLong(“key1”, 666L).navigation();

通过ARouter在module间共享对象,实现module间通信。

比如:我们有一个账号模块 business:account ,提供了登录、登出、用户信息查询等业务。

同级的其他模块,如何跟账号模块通信?获取用户的登录状态以及用户相关信息?

public class AccountBean {

private String name;

private int age;

//…

}

public interface IAccountService extends IProvider {

void login(Context context);//登录

void logout(Context context);//登出

AccountBean getAccountBean();//获取账号信息

}

对外的数据结构和接口定义。

@Route(path = BusinessRoutePath.ModuleAccount.ACCOUNT)

public class AccountServiceImpl implements IAccountService {

//…

}

bussiness:account模块中的实现。

IAccountService accountService = ARouter.getInstance().navigation(IAccountService.class);

accountService.login(activity);

AccountBean bean = accountService.getAccountBean();

但是问题来了:

同层的其他模块,如何,能拿到ARouter的path?

同层的其他模块编译时,如何,共享AccountBean类、IAccountService接口?

这就是模块之间的编译隔离,带来的问题。

我们很自然的想到了framework模块,或者base层的其他模块。

我们只要将这些path定义、AccountBean类、IAccountService接口,下沉到base层,就可以实现编译上的代码共享。

如此一来,就带来了,另一个问题:代码的中心化问题

2、代码的中心化

简单的path字符串定义,放在framework倒是还好。

如果所有business模块对外提供的接口和数据结构,都定义到framework的话,问题就有点严峻。

将会破坏:组件的 可替代性可重用性组件间耦合度

因为framework是基础模块嘛,所有business模块都依赖的模块,如此,不管你的business1模块是否依赖business2模块的对外接口,都会存在这一层依赖。

模块间的代码边界出现一些劣化。缺少了编译上的隔离。许多模块将会变得不够“独立”了。

可替代性可重用性 越来越弱,想要替换或者复用某个business组件将变得越来越难。

将会导致,我们很难知道,哪些business对哪些business 接口有依赖。

同时,framework模块随着功能迭代,会不断膨胀。

这就是,中心化的问题。

于是我们很自然的想到了一个解决方案:

实现了另一种接口暴露的形式——“.api化”。

将 business模块 对外提供的接口单独抽到 business-api 模块中。其他依赖他的模块只需要依赖他的business-api即可。

这个方案如何实践下去呢?

微信的api化方案

微信团队出了一个很巧妙的方案,这个方案对android的组件化开发,产生了非常深远的影响。

后面很多做组件化开发的团队,在解决中心化问题基本都会用到类似的方案。

mp.weixin.qq.com/s/6Q818XA5F…

以下为,微信官方博客的原文引用:

使用方式和思路都很简单。对于java文件,将工程里想要暴露出去的接口类后缀名从“.java”改成“.api”,就可以了。

而且并不只是java文件,其他文件如果也想暴露,在文件名后增加".api”,也一样可以。

当然,要让工程支持这样的方式,gradle文件肯定会有一点改变。

它的实现原理也相当简单:自动生成一个“SDK”工程,拷贝.api后缀文件到工程中就行了,后面其他工程依赖编译的只是这个生成的工程。简单好用。

api方案有点类似于android的AIDL的思路。

微信API方案的变种

gradle 根据src/api文件来,自动生成{moduleName}-api模块。

如果,src/api文件不存在,将不会自动生成 {moduleName}-api 模块。

通过API模块来解决代码中心化问题带来的好处:

  1. 让各个business的之间的依赖明确

  2. 让business对外提供的接口明确。

从而加强了模块的:可替代性

只要两个business对外提供的API一致,就可以相互替换。

3、单独编译、测试 business的单个模块

模块变多了,项目变大了,整个项目的编译速度变慢了。

业内有两种常用做法。

  • 方案一:动态配置 build.gradle。

只要让单个的组建能编译成APP就能单独测试。

  • 方案二:多壳APP

方案来自,在聚美优品。

这里需要注意:假如,Demo1是business1的壳APP。那么Demo1还需要依赖哪些businessXXX呢?

刚好,前面做的api化,能排上用场。

business1依赖的businessXXX-api模块对应的businessXXX模块,Demo1也需要依赖。

为甚?因为,business1依赖的businessXXX-api模块,意味着,business1需要依赖 businessXXX提供的功能,比如要跳转到businessXXX的activity?或者,要获取businessXXX的对象。

4、模块变多了,gradle代码同比增长,gradle 代码复用
  • 版本号统一管理,依赖的统一管理
  • 方案一:Extra properties

在项目跟目录的build.gradle文件中配置Extra属性

如此可以实现统一管理版本号,和依赖。

但是,但是,但是,这个方案存在明显的缺陷。

  • 不支持,自动补全

  • 不支持Find Usages,查找所有应用的地方

  • 使用时,不支持点击跳转

严重影响开发体验。

  • 方案二:buildSrc

  • 支持,自动补全

  • 支持,Find Usages

  • 支持,点击跳转

  • 更完美的语法高亮

  • gradle文件复用

版本和依赖做到了统一管理,但是每个module都有各自的build.gradle,重复的build.gradle代码依然没有复用。

我们可以通过apply from:"xxx.gradle"的方式来复用gradle代码。

如下图

如上,我们可以在base.gradle中为每一个项目添加配置统一的编译逻辑,如:kotlin的支持,java版本的修改,maven库上场的逻辑等等

5、模块间:string、drawable、value、layout等,资源名冲突问题

如何防止资源名冲突?

比如businessA 和 businessB都在drawable目录下,都有一张同名的图片。

这两张图片只有一张会被打包到apk中,被使用。

这样就容易出现混乱。

这个问题比较好解决。让每个模块的资源名固定一个前缀。只要模块之间的前缀不一样就不会冲突。

gradle的resourcePrefix配置,刚好符合我们的需求。

如下配置,如果module中存在资源不以app_开头,**lint走查会报warnning。**注意不会编译失败。

android {

resourcePrefix ‘app_’

}

如下截图的warning:

6、由于多module分层的项目结构,导致 R.class 冗余

可以通过booster的资源内联工具解决,R类的冗余。

详细可以

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享

自己查看booster官网,booster是didi开源的一个插件。booster.johnsonlee.io/feature/shr…

7、模块间,公共资源string、drawable、layout等如何共享?

没有找到很好的解决方案。

每个方案都有缺陷

比如说,business1和business2都要用到同一张图片。

那么这张图片该放到哪里呢?

  • 1、把他放到api模块里来共享

资源这种,并非功能依赖,放到api模块也不太合适。

因为这样可能造成business1和business2模块原本没有关联也没有依赖;

但因为共用同一个资源,却导致存在了依赖。

  • 2、在business1和business2中都放一个图片

Android 组件化面试必备(1),Android面试题2020相关推荐

  1. Android 组件化面试必备,android输入法开发源码

    如果我们要为某个已经存在的组件,重新开发一个新组件,将变得非常可行. 组件内的重构也将变得非常可行. 新的组件的设计只要保证对外提供的接口,完全符合,旧组件对外提供的接口 5.组件的热插拔,成为可能( ...

  2. android组件化数据生命周期,Android组件化开发实践(五):组件生命周期管理

    每个Android应用启动时,都会先创建一个Application.通常在Application里我们会做一些应用初始化的操作,常见的有第三方SDK初始化.在应用组件化之后,组件与壳工程是隔离开来的, ...

  3. app安卓开发教程!Android组件化架构实践,高级面试题+解析

    前言 互联网时代的到来,让我们获取知识变得更加简单,理论上讲只要你想学,便会有不尽的知识等你,只要方法得当,够努力,任何人都可以都有可能成为大牛. 自己在努力的基础上,还学习了一些高效的学习方法,让我 ...

  4. 腾讯技术团队人手一份的Android组件化实战笔记(含得到、微信、美团、爱奇艺APP架构项目及源码)

    前言 以前的Android开发大多用的中心化管理思想,将相同的资源集中进行管理.随着项目的发展,弊端渐显:集中管理的资源越来越多,多人开发也越来越麻烦,时常牵一发而动全身. 尤其是在大公司或者是大项目 ...

  5. Android组件化与插件化开发项目实战整理分享(含支付宝、360、美团、滴滴等大厂项目实战)

    小公司不说,但是在大公司的项目发展到一定程度,就必须进行模块的拆分.模块化是一种指导理念,其核心思想就是分而治之.降低耦合.而在 Android 开发的实践,目前有两种途径来实现,一个是组件化,一个是 ...

  6. Android组件化之终极方案

    版权声明:本文为博主原创文章,欢迎大家转载! 转载请标明出处: http://blog.csdn.net/guiying712/article/details/55213884 ,本文出自:[张华洋的 ...

  7. Android组件化方案

    版权声明:本文为博主原创文章,欢迎大家转载! 转载请标明出处: http://blog.csdn.net/guiying712/article/details/55213884 ,本文出自:[张华洋的 ...

  8. Android 组件化方案,从入门到精通

    Android组件化项目地址:Android组件化项目AndroidModulePattern Android组件化之终极方案地址:http://blog.csdn.net/guiying712/ar ...

  9. Android组件化开发简单示例

    Android组件化示例代码github地址:https://github.com/respost/ModuleDemo 一.组件化初始模型 1.通过一个简单的android项目初始架构图来了解组件化 ...

最新文章

  1. SAP QM 采购订单收货时没有Vendor CoA就不让收货过账的实现
  2. php 如何让图片循环显示图片,[宜配屋]听图阁
  3. 机器学习笔记:triplet loss
  4. unity的自带特性
  5. Zend Studio使用教程:使用PHPUnit检测代码(四)
  6. 编译原理:全片知识难点总结
  7. eclipse中YAML文件编辑插件:Yaml Editor插件安装
  8. SAP HANA解读-2012 SAP商业同略会分享
  9. jvisualvm工具使用
  10. springcloud 微服务鉴权_推荐 1w+ 星标的 SpringCloud 微服务项目,开发脚手架
  11. 解决Ubuntu 14.04下CodeBlocks缩进异常问题
  12. 对给定数组升或降排序
  13. 【Android自定义控件】仿京东首页的京东快报,自动向上滚动的广告条
  14. python 会议室预约系统解决方案_会议预约管理系统解决方案
  15. iOS开发图片合成,多张图片合成一张图片
  16. 【067】Color Hunter-用图片搜索配色方案
  17. 不可错过的爬虫实例(一):教你爬取优美图库
  18. mysql数据库管理维护_深入浅出MySQL 数据库开发 优化与管理维护 第3版
  19. IT未来发展五大趋势
  20. c语言字符型常量计算,c语言字符型常量和变量.doc

热门文章

  1. 这几款好用的工具推荐给你
  2. UniApp + SpringBoot 实现接入支付宝支付功能和退款功能
  3. 课堂笔记typro使用方法
  4. 电子招标项目代码笔记
  5. 高级开发面试题,朋友给的,怕忘了
  6. set 有序吗js_JavaScript Set 集合
  7. 吃野生动物真的是“猎奇”的生物本能驱动的?
  8. 君正Zeratul开发(2)——uboot启动分析
  9. 华为鸿蒙如何兼容多系统,华为鸿蒙系统支持的手机型号有哪些?鸿蒙手机操作系统支持机型公布[多图]...
  10. B2B,B2C,C2B,C2C - 电子商务模式的几个概念