Android组件化实践

一、为什么要组件化?组件化有哪些好处?

网上提到的组件化的好处有很多,这里我就仅列举几个比较明显的好处。

1.代码隔离,实现被动解耦

情景a 小王想实现一个右上角有“X”号的dialog,但是他发现基础UI库里dialog没有这个按钮,于是小王想偷偷在基础组件库里写一个tag,用于标记dialog是否右上角有“X”号。

(组件化前)小王偷偷写入成功,大家纷纷效仿小王,最后基础库里的dialog一共有十几处tag用于标记状态。后来,UI大改版,大家发现这个dialog代码过于复杂只能重构。
(组件化后)小王发现基础库的代码是远程依赖,自己并没有修改权限,只好作罢。他通过继承的方式,写了一个属于自己模块的dialog。

情景b: 小张是一个邋遢的人,他写代码从不一口气写完。有一天,小张重构了BaseFragment,但是他写了一半,项目无法编译就提交了,而且他还请了十天的假。

(组件化前) 项目组正在紧急修复一个bug,但是发现怎么也无法编译成功。经查,是小张改了BaseFragment,改的异常复杂,大家还不敢修复,然后又联系不到小张。最终导致项目delay了一个星期。
(组件化后) 项目组一直依赖的是maven库的上版release包,base库虽然代码不能编译,但是app并不直接依赖源码。项目正常推进。

情景c: 小李和小王分别在开发两个模块,小李发现小王im聊天类写的非常的出色,所以准备直接引用小王写的类。但是小王准备对该模块进行升级

(组件化前)两人都愉快的开发,直到上线的那天,小李发现自己im消息加载不出来头像,于是他甩锅给小王。后来两人为此闹的不可开交。
(组件化后)im属于基础组件,要求所有暴露在外的接口必须保持不变。小王升级了组件以后,对小李没有任何影响。

2.工程有了层次感,更容易找到自己的“一亩三分地”

情景a:小刘是一个新来的同学,他接到一个需求,说要给视频直播间加一个dialog。

(组件化前)小刘一顿操作,给直播间一个按钮加了一个dialog,但他不知道音频直播间也在用这个模块,后来线上出现了大批崩溃。
(组件化后)小刘通过名字迅速找到了LiveComponent模块,因为AudioLiveComponent是另外一个模块,所以修改了并没有产生影响。

3.组件化后的模块就像摆在货架的商品,其他app也可以快速集成使用

情景a:A公司日益壮大,一个App已经无法满足公司的雄心壮志,A公司决定要写一个新的以直播为导向的app

(组件化前)程序员们开始疯狂从原有的app上复制代码。从基础框架、网络请求、图片加载 到 数据库、原子参数。后来服务端决定对接口进行升级,程序员们又开始一个一个项目的修改代码
(组件化后)程序员只参照文档 一行gradle一个组件,迅速搭建了app架子。服务端进行接口升级后,各app仅仅把自己依赖的版本号进行升级,就完成了整个app网络请求的改造。

二、组件化长什么样子?有哪些规范?

1.组件化一般分为:

App壳:不参杂任何逻辑,只是把各个业务组件整合在一起。
业务组件层:承担业务功能,不可复用,程序员日常迭代的地方。
功能组件层:封装一些基本的功能,包括日志、分享、登录等。一般不进行修改,供上层业务调用。
基础库:非常基础的库,能干的事情较单一,并且不承担任何业务逻辑。

下图以类似“美团app”为例


想象中的美团app架构

注意:图中的依赖关系是自上而下的,同级之间禁止依赖。

2.那组件化的代码又是什么样子呢?以为做的个人app为例

我的项目中有:大厅、直播、彩票等上层模块。接下来是网络请求、基础base架构模块。他的文件结构是这样的


我自己的app文件架构

项目是不是看起来清新又直白。这就是组件化的魅力。

三、利用阿里云效搭建自己的组件库

0.创建一个组件

a:通过Androidstudio可以为我们自动创建一个组件。


第一步:创建module

b:我们一般选择Android library

第二步:创建一个Android Library

c:然后起一个名字,模块名我比较喜欢加Component(为了和基础组件区分),包名则省略这个后缀。

第三步:起名字

d:然后我们重新build一下,新模块就建立好啦,模块有一个三道杠的标示。

第四步:看看我们干的好事
1.进入阿里云效,选择制品仓库,选择maven仓库。

根据提示配置gradle

步骤一:请在build.gradle中设置仓库的访问凭证。
group '[GROUP_ID]'
version '[VERSION]'
def artifactId = '[ARTIFACT_ID]'
apply plugin: 'maven'
uploadArchives {
  repositories {
    mavenDeployer {
      repository(url: 'xxxxx') {
        authentication(
          userName: '***',
          password: '***'
        )
    }
    snapshotRepository(url: 'xxxxx') {
      authentication(
        userName: '***',
        password: '***'
      )
    }
      pom.version = '$project.version'
      pom.artifactId = '$artifactId'
      pom.groupId = '$project.group'
    }
  }
}
步骤二:设置仓库下载配置
配置
allprojects {
  repositories {
    maven {
      url 'https://maven.aliyun.com/repository/public'
    }
    maven {
      credentials {
        username '***'
        password '***'
      }
      url 'xxxx'
    }
    maven {
      credentials {
        username '***'
        password '***'
      }
      url 'xxxx'
    }
  }
}

但是我不听他们的建议,这边我介绍一种比较方便的配置方法:

在模块的build.gradle里加入
ext {
    isRelease = false
    componentVersion = '0.0.1'
}

在下面的任意地方加入(因为gradle是按顺序编译的,引用必须要放在ext之下)
apply from: "publish.gradle"
这项目文件夹下创建一个publish.gradle 
apply plugin: 'maven-publish'
publishing {
    publications {
        debug(MavenPublication) {
            groupId maven_component_groupId  //gradle.properties里写入对应的值
            artifactId [project.name](http://project.name/)
            version "${isRelease ? componentVersion : "${componentVersion}-SNAPSHOT"}"
            artifact("$buildDir/aar/${[project.name](http://project.name/)}-debug.aar")
        }
    }
    repositories {
        maven {
            url "${isRelease ? maven_release_repo : maven_snapshots_repo}" //gradle.properties里写入对应的值
            credentials {
                username maven_user //gradle.properties里写入对应的值
                password maven_password //gradle.properties里写入对应的值
            }
        }
    }
}

这样,我们每次升级版本的时候,只用修改对应模块build.gradle里版本号就ok了
然后我们依次执行下面两行命令,将模块推送到远端:

./gradlew :MusicComponent:build
./gradlew :MusicComponent:publish

然后我们在引用模块的时候,只需要在上层模块build.gradle

implementation "${maven_component_groupId}:MusicComponent:0.0.1-SNAPSHOT"

这样我们就实现了远程依赖。接下来,我们只要一步一步更改版本号就可以完成组件升级。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

  • 0 背景 早前严选 Android 工程,业务模块和功能模块不多,工程较为简单,全部的业务代码均在主 app 工程...
    zyl06阅读 6,185评论 10 54
  • 引子 一般情况下,一个 Android 项目,随着业务的发展和扩张,会有许多 Activity、Fragment ...
    修之竹阅读 1,357评论 2 4
  • 编译时间越来越长,时间=生命,我要救命。 项目框架 最开始项目只有一个app,项目结构很简单,就是一个业务modu...
    展翅而飞阅读 4,472评论 5 18
  • 一、背景 随着APP版本不断的迭代,新功能的不断增加,业务也会变的越来越复杂,APP业务模块的数量有可能还会继续增...
    please边去阅读 526评论 0 1
  • 前言 相信各位小伙伴们对组件化开发都不陌生了,本文只对我所理解和使用的组件化开发方案做一个总结,有不正确或者需要改...
    小豪丶ace阅读 577评论 0 2