第1章 组件单独调试与集成发布

1、组件化思路

“聚合和解耦是项目架构的基础”,站在组件化项目角度,第一步期望子组件可以作为APP单独调试和壳APP集成发布。好处在于开发者在一个子项目中把子组件作为一个子app开发,而不影响别人。APP上线,发布者只需关心是否合并子组件功能。

2、单独调试与集成发布需求拆解

  • 1、单独调试:指通过一个标志isRunAlone, 若isRunAlone==true,当前lib项目转化为app项目,反之为lib项目,移除调试代码
  • 2、集成发布:指壳工程,IDE编写代码时,不能引用子组件代码,做到编写隔离,而编译时,又要将子组件代码编译到主项目中,最好配置是在壳工程中gradle.propetties,建议也要支持扩展方法addComponent,以函数方式支持

3、核心逻辑

  • 1、初始化当前项目
  • 2、获取当前任务类型
  • 3、若当前是壳工程,支持编译隔离
  • 4、若当前是子组件,支持单独调试和发布
3.1 示例代码
    void apply(Project project) {
        this.mProject = project

        //1、初始化当前项目
        initAlone(project)

        //2、判断当前任务 只有assemble任务才添加依赖
        assembleTask = getTaskInfo(project)

        //3、当前是壳工程 不许被引用
        if (isMainApp(project)) {
            //运行壳工程配置
            runMainApp(project)
            //添加配置依赖
            compileComponents(assembleTask, project)
            //添加扩展方法 (选项) 参数
            project.ext.addComponent = { dependencyName -> addComponent(dependencyName) }
            return
        }

        //4、支持单独调试和发布
        runAlone(project)

    }
3.2单独调试
    private static final String DEBUG_DIR = "src/main/debug/"

    /**
     * 支持单独调试和发布
     */
    private void runAlone(Project project) {
        //1.找当前module的状态
        boolean isRunAlone = fetchAloneStatus(project)
        if (isRunAlone) {
            project.apply plugin: 'com.android.application'
            log("apply plugin is " + 'com.android.application')
            project.android.sourceSets {
                main {
                    //debug模式下,如果存在src/main/debug/AndroidManifest.xml,则自动使用其作为manifest文件
                    def debugManifest = "${DEBUG_DIR}AndroidManifest.xml"
                    if (project.file(debugManifest).exists()) {
                        manifest.srcFile debugManifest
                    }
                    java.srcDirs = ['src/main/java', "${DEBUG_DIR}java"]
                    res.srcDirs = ['src/main/res', "${DEBUG_DIR}res"]
                    assets.srcDirs = ['src/main/assets', "${DEBUG_DIR}assets"]
                    jniLibs.srcDirs = ['src/main/jniLibs', "${DEBUG_DIR}jniLibs"]
                }
            }
        } else {
            project.apply plugin: 'com.android.library'
            log("apply plugin is " + 'com.android.library')
            //main下删除所有debug目录下的文件
            project.android.sourceSets.main {
                //默认这个位置,为代码清晰
                manifest.srcFile 'src/main/AndroidManifest.xml'
                //删除所有debug目录下内容
                java {
                    exclude 'debug/**'
                }
                res {
                    exclude 'debug/**'
                }
                assets {
                    exclude 'debug/**'
                }
                jniLibs {
                    exclude 'debug/**'
                }
            }
        }
    }

4、插件编写原则

1、单一职责:一个插件只做好一件事,不要与其他组件化插件功能耦合。
2、配置化:用户最小情况修改代码,可以带来稳定
3、易用性:以用户为中心,编写代码提供插件支持,减少生僻概念,支持用户惯性写法

  • 1、单一职责
    单独调试和集成发布功能属于通用功能,即使不做插件化,在开发中也有好处。过于强大插件功能,易用性反而降低,进而限制了

  • 2、配置化
    在根目录下gradle.propetties配置isRunAlone,就可以设置设置项目中组件lib与app形式切换
    在空壳app下gradle.propetties配置,就可以动态引入子组件

###是否为主APP
isMainApp=true

###配置方式接入组件
debugComponent=':module_main',\
  ':module_girls',\
  ':module_news'
releaseComponent=':module_main',\
  ':module_girls',\
  ':module_news'
  • 易用性 支持壳工程 addComponent(':module_main')函数,在gradle中引入子组件,配置还支持容错性trimAll不可见字符

5、使用示例

根目录配置gradle.propetties

##集成与独立模式
isRunAlone=false

1、壳工程
gradle配置

apply plugin: 'thorAlone'
并且删除原来的app引用
//apply plugin: 'com.android.application'

//或采用这种方式
dependencies{
    //组件解耦采用这种方式  assemble 才会引入依赖 build并不引入达到组件间代码隔离
    addComponent(':module_main')
    addComponent(deps.support.multidex)
}

gradle.propetties

###是否为主APP
isMainApp=true

###配置方式接入组件
debugComponent=':module_main',\
  ':module_girls',\
  ':module_news'
releaseComponent=':module_main',\
  ':module_girls',\
  ':module_news'

2、子组件配置
gradle配置,删除sourceSets

apply plugin: 'thorAlone'
并且删除原来的lib引用
//apply plugin: 'com.android.library'

//删除 sourceSets
//sourceSets{
//main{}
//}

子组件代码配置


6、项目代码

https://github.com/yinlingchaoliu/AndroidComponent

插件位置
AndroidComponent/thor_alone_gradle_plugin

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