android组件化架构 速览android组件和使用技巧

从2017年开始,只有几个大厂在做组件化,今天已经开花结果。越来越多的团队和项目被组件化了。我相信即使你没有做过组件化项目,你也早就听说过组件化。但是组件开发有一定的技术门槛。有很多大神写过相关的文章,但是没有几篇是通俗易懂的。简单的不多。不,我愿意不要脸的冒...

从2017年开始,只有几个大厂在做组件化,今天已经开花结果。

越来越多的团队和项目被组件化了。

我相信即使你没有做过组件化项目,你也早就听说过组件化。

但是组件开发有一定的技术门槛。

有很多大神写过相关的文章,但是没有几篇是通俗易懂的。简单的不多。

不,我愿意不要脸的冒险,用通俗易懂,浅显易懂的方式来谈组件开发。如果对你有一点启发,请记得回来给大叔一个

一、单项目开发->:多模块分层开发

这种等级结构有什么用?

分解成多模块的项目结构,是基于组件的开发吗?

当然不是。多模块分层项目结构只是组件开发的一部分。只是组件开发的基础。

大叔,搜了很多资料,发现组件开发并没有严格的定义。

当然,我们也不需要太纠结于组件开发的定义。

我们更关注这种开发思路对项目的好处,以及如何在团队中应用。

第二,组件化的思想和优势

以下是我的理解。如果有任何异议,请提出来讨论。

1.将一个大型项目分解成多个模块,分解的过程就是一个简化的过程。

尤其是在大型团队和项目中,组件化的优势会更加突出。

把一个大项目分解成小项目,相当于把一个复杂的问题分解成相对简单的问题。

每个成员可以专注于他相关业务的模块。

2.分层模块结构。同一层的模块之间有代码隔离,这是编译中的隔离。

同一层的代码不能互相调用。底层代码也不能调用上层。

编译的这种隔离带来了模块之间的高度解耦。

明确模块的依赖关系。

3.更高的可重用性。

(如果组件设计的系统构建正确),比传统的整体设计具有更高的复用性。

什么是组件?什么是模块?

组件强调重用,模块强调职责划分。他们没有很严格的分工。

一个满足复用性要求的模块,那么这个模块就是一个组件。

基础层的模块必须是可重用的。如果项目设计得好,业务层可以重用,每个模块都可以成为一个组件。

可重用性是组件化的核心。

那么,这种架构在技术上是否也适用于中级阶段的架构呢?

4.每个组件都有可替代性(如果构建正确的话)

如果我们想为现有组件重新开发一个新组件,这将变得非常可行。

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

只要新组件的设计确保外部接口与旧组件提供的接口完全一致。

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

想象一下,当APP运行时,业务中的组件可以动态加载或卸载。

那么我们就很容易实现组件的懒加载:加载用户使用的组件。之后就可以卸载了。

6.组件的独立编译和测试使之成为可能(如果构建正确的话)。

一次搭建一个大的android项目大概需要5分钟,很浪费时间。

拆成多个组件后,如果每个组件都可以单独构建和测试,那么开发效率会大大提高。

上面讨论的这些优势并不是简单的将单个项目拆分成分层多模块项目结构就能获得的。

要获得这些优势,还有很长的路要走,我们还需要解决很多问题,才能让我们的项目具备上面提到的优势。

二、组件化后会面临哪些问题?怎么解决?

1.模块之间如何优雅地通信?

通过路由器交流。

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

通过路由器跨模块跳转活动@Route(path = "/test/activity")//申明路由public class YourActivity extend Activity { ...}//通过路由启动ActivityARouter.getInstance().build("/test/activity").withLong("key1", 666L).navigation();***代码

模块间的通信是通过Router在模块间共享对象来实现的。

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

同级别的其他模块如何与账户模块通信?获取用户的登录状态和用户相关信息?

public class AccountBean { private String name; private int age; //....}public inte***ce IAccountService extends IProvider { void login(Context context);//登录 void logout(Context context);//登出 AccountBean getAccountBean();//获取账号信息}***代码

外部数据结构和接口定义。

@Route(path = BusinessRoutePath.ModuleAccount.ACCOUNT)public class AccountServiceImpl implements IAccountService { //.....}***代码

业务中的实现:帐户模块。

IAccountService accountService = ARouter.getInstance().navigation(IAccountService.class);accountService.login(activity);AccountBean bean = accountService.getAccountBean(); ***代码

但问题是:

同一楼层的其他模块,如何获取Router的路径?

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

这就是模块间

编译隔离

导致的问题。

我们自然会想到框架模块,或者基础层的其他模块。

只要把这些路径定义,AccountBean类,IAccountService接口,

下沉到基础层

,就可以实现编译中的代码共享。

这样一来,就带来了另一个问题:

代码的中心化

2.代码集中化。

简单的路径字符串定义,最好放在框架里。

如果业务模块提供的所有接口和数据结构都定义在框架里,问题就有点严重了。

会破坏:

可替代性

,可重用性

,组件间的

耦合度

因为框架是基础模块,所有的业务模块都依赖于它,所以不管你的business1模块是否依赖于business2模块的外部接口,都会有这层依赖。

模块之间的代码边界有些恶化。编译中缺乏隔离。很多模块会变得不那么“独立”。

可替代性可重用性越来越弱,替换或重用一个业务组件会变得越来越困难。

这将使我们很难知道哪些业务依赖于哪些业务接口。

同时,框架模块会随着功能迭代而扩展。

这就是集权的问题。

所以我们很自然地想到了一个解决方案:

实现了另一种形式的接口公开。API”。

由业务模块提供的接口被单独绘制到业务api模块中。其他依赖他的模块只需要依赖他的业务——API。

这个计划怎样才能付诸实施?

微信的api方案

微信团队想出了一个巧妙的方案,对android的组件开发影响深远。

未来很多做组件开发的团队基本都会用类似的方案来解决中心化问题。

以下为微信官方博客原话:

用法和思路都很简单。对于java文件,只需更改您希望在项目中从”中公开的接口类的后缀名称。Java“to”。api”。

而且不仅仅是java文件。如果想要暴露其他文件,请添加”在文件名之后。。api”,一样好。

当然,要让项目支持这种方式,gradle文件肯定会有一点变化。

它的实现原理也相当简单:自动生成一个“SDK”项目,只需***。api后缀文件导入到项目中,以后的其他项目都依赖于这个生成的项目。简单易用。

这个api有点类似于android的AIDL的想法。

微信API方案的变种

Gradle根据src/api文件自动生成{moduleName}-api模块。如果src/api文件不存在,则不会自动生成{moduleName}-api模块。通过API模块***代码解决代码中心化问题的好处:

让各个business的之间的依赖明确让business对外提供的接口明确。

从而增强模块的可替代性

只要两个业务提供的API一致,就可以互相替换。

3.单独编译和测试单个业务模块。

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

业内有两种常见的做法。

方案一:动态配置 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 propertiesdeveloper.android.com/studio/buil…docs.gradle.org/current/use…在项目跟目录的build.gradle文件中配置Extra属性如此可以实现统一管理版本号,和依赖。但是,但是,但是,这个方案存在明显的缺陷。不支持,自动补全不支持Find Usages,查找所有应用的地方使用时,不支持点击跳转严重影响开发体验。方案二:buildSrc支持,自动补全支持,Find Usages支持,点击跳转更完美的语法高亮gradle文件复用版本和依赖做到了统一管理,但是每个module都有各自的build.gradle,重复的build.gradle代码依然没有复用。我们可以通过apply from:”xxx.gradle”的方式来复用gradle代码。如下图如上,我们可以在base.gradle中为每一个项目添加配置统一的编译逻辑,如:kotlin的支持,java版本的修改,***ven库上场的逻辑等等

5.模块之间:字符串、drawable、值、布局等。,资源名称冲突。

如何防止资源名称冲突?

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

这两张图只有一张会打包成apk使用。

这就容易产生混淆。

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

Gradle的resourcePrefix配置正好满足了我们的需求。

配置如下。如果模块中有不以app_,开头的资源,lint walkthrough将向warnning报告。注意编译不会失败。

android { resourcePrefix 'app_'}***代码

下面截图的警告:

6.由于多模块的分层项目结构,导致了R.class冗余。

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

可以详细查看booster官网。booster是滴滴开源的一个插件。
booster . johnsonlee . io/feature/SHR…

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

没有找到好的解决方案。

每个方案都有缺陷。

例如,业务1和业务2使用相同的图片。

那么我应该把这张照片放在哪里呢?

1、把他放到api模块里来共享资源这种,并非功能依赖,放到api模块也不太合适。因为这样可能造成business1和business2模块原本没有关联也没有依赖;但因为共用同一个资源,却导致存在了依赖。2、在business1和business2中都放一个图片如此会增大包体3、在business1和business2中都放文件名同名的图片,让编译时资源合并的时候只使用同一张图片。如此一来,放开各个模块资源命名,也容易导致开发时发生冲突。自定义lint规则,让存在common和{moduleName}两种前缀?4、将这张图片下沉到base层,如:framework模块,或者,单开一个lib-resource如此一来,将会出现资源中心化问题。

以上方法有些瑕疵,大叔还没找到优雅的方式。如果你有什么好的想法,一定要留言告诉大叔,大叔在这里谢谢你了。

8.各个业务模块之间可以有直接的依赖关系吗?

千万不要这样。

如果:业务/设置直接依赖于gradle配置,业务:帐户。

那么编译中的代码隔离就被彻底破坏了。先不说组件的复用性可替代性

实施项目(“:业务:账户”)***代码

9.如何分配应用程序的生命周期?

各组件如何获取Application.attach()、Application.onCreate()、Application.onTerminate()等回调?

待续

10.组件生命周期管理

未完待续,踩坑悟道后,再写。

1.组件可以热插拔。

未完待续,踩坑悟道后,再写。

12.等等,未完待续。

继续探索

第三,升华

最后,让我们回到组件化本身。

组件开发不仅仅是一个多模块的层次化项目结构;他不仅仅是一座建筑;他是一种架构思想,一种追求模块复用的精神。

有人说组件开发对小项目来说没必要。大叔不这么认为。小项目还是适合组件化,除非你的团队只有一个项目,而且项目几乎不需要迭代。跨项目重用组件也是一个令人兴奋的优势。

前几年在台湾中部听烂技术,与组件化架构不谋而合。

本文来自一纸枕书投稿,不代表舒华文档立场,如若转载,请注明出处:https://www.chinashuhua.cn/24/502263.html

打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
() 0
上一篇 04-13
下一篇 04-13

相关推荐

  • 酒吧管理系统有哪些 酒吧管理系统架构

    随着科技的进步,酒吧管理进入了一个新的阶段。许多老板已经开始使用酒吧管理软件来更好地管理商店,员工和其他事情。那么,开酒吧该如何选择酒吧管理软件呢?这里科普下的简易酒吧管理系统,和以前的单机收银软件一样,功能单一,无法满足现代酒吧的管理需求。而且单机系统更

    2023-07-26 12:35:01
    426 0
  • 互联网架构师是做什么的 互联网架构师就业前景

    看看软件架构师的职责看看软件架构师的职责。& gt丹尼尔麦卡洛在Unsplash上拍摄的照片。这篇文章和我以前的文章完全不同。现在有一段时间,很想写一些理论文章,分享一下自己创业时成为软件架构师的想法。先说我们日常工作中真正做的事情。介绍如果你看了我写的一些东西,你就

    2023-07-20 02:30:01
    106 0
  • 网络架构设计 常见的网络基础架构

    最近大黄在整理SDN相关内容,和大家分享其网络架构。众所周知,SDN是一个控制平面和转发平面分离的网络。它具有开放的可编程接口,可以集中控制网络,从而实现网络服务的自动配置。今天,我们来看看它的网络结构。SDN网络层级SDN网络有三个层次,即:应用层: 防火墙, NAT, QoS

    2023-07-16 12:14:01
    400 0
  • 云服务架构的服务特点有哪些 揭晓云服务架构的5大特点

    如何保证信息系统中企业数据的安全、持续、稳定运行,是目前信息管理部门面临的首要问题。网络发展产生的云产品越来越受站长们的欢迎,那么我们常说的云服务器有什么特点呢?1。云服务器更方便操作升级传统服务器中的资源有限。如果想获得更好的技能,只能升级云服务器。所谓

    2023-07-08 09:27:01
    507 0

评论列表

联系我们

在线咨询: QQ交谈

邮件:admin@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信