美文网首页
Android 浅解组件化-路由框架(1)

Android 浅解组件化-路由框架(1)

作者: ZuYuan | 来源:发表于2019-03-09 23:46 被阅读0次

    前言

    之前学习组件化-路由的时候也是花费了不少的时间,其实学习技术都是这样,自己弄懂了大部分东西之后就会觉得这个知识好像并不是那么难。
    这里的 “ 组件化-路由技术 ” 分成两篇文章讲解,确实内容略多一点,第一篇主要就是讲解组件化,而第二篇就主要讲解路由知识,这里是第二篇文章的链接
    我尽力讲得更加仔细一点,希望刚接触这项技术的小伙伴能够看得懂。

    组件化的作用

    组件化技术主要是进行项目比较大的团队才会采用的,想必它的作用很多小伙伴是清楚的了,我就简单提几点就行了。

    1. 提高编译速度: 该技术可以实现单独一个组件作为一个Application进行编译运行,例如我只想测试一下“登录、注册”组件,而我不必编译、运行整个项目,这样就可以提高我的开发效率。
    2. 解耦程度大: 解耦程度大不多解释,因为毕竟一个组件都可以单独运行了,你想它的解耦程度大不大呢?特别是将common(公共层)抽出来之后,用起来是真的舒服~
    3. 利于团队开发:这一点上感触颇深,在任务分配完成之后,就是感觉跟其它人的代码就完全分割开来了,写代码的过程很舒服,而且在git管理代码的过程中失误率也会小很多。

    组件化实现

    组件化实现比较轻松,下面我会将完整步骤都描述出来。

    1. 统一每个组件的配置文件
    第一步就是新建几个组件,选中项目new module就可以了,结果如下图所示:

    新建组件

    在这里,我的想法是app作为应用壳组件,它负责APK的打包,管理其它组件,而没有业务逻辑;lib_common是公共层组件,是放置共用的网络请求、工具类的地方;而lib_home、lib_chat组件就是我们的业务逻辑组件。
    如上图所示,每一个组件都有自己的build.gradle文件,我们肯定需要配置文件(.gradle)里信息的统一,防止私自修改gradle文件而影响整个项目的编译运行。我们需要创建一个config.gradle(上图所示)来统一gradle文件,config.gadle文件包含以下信息:


    配置文件

    这一个config.gradle文件需要导入到项目配置文件中去,我们需要在project的build.gradle文件下代码的顶部加上apply from: "config.gradle"来将我们的配置文件导入项目。接下来只需要在每个组件的build.gradle文件中这么使用:

    单一组件bild.gradle文件

    2. 设置组件单独运行时的AndroidManifests.xml文件
    在讲之前,我们先做一件事,由于common组件作为共用层,它肯定不需要单独运行,所以我们先将它导入其它的组件,按照添加三方库的办法,在其它组件的build.gradle文件中添加代码implementation project(':lib_common'),以此导入本地库,然后,将app组件下的res文件全部导入common组件中去(layout目录就不用了,它就是app组件私有的),由于已经依赖了common组件,那么app中res的所有文件就可以删除了,不然就多了,而且重名。

    我们可以打开某一个组件下的AndroidManifests.xml看一下,它没有<application></application>标签,因为它此时是作为一个来使用的,它不能够使用应用标签。同理,它也不能配置该标签下的信息,例如应用名、主题之类的。按照三方库形式导入其它组件后,这个manifests文件上的信息会被合并到另外一个组件的manifests文件上去。
    为了使得我们的组件可以单独运行,我们需要单独为它创建一个manifests文件,我们在Project方式查看项目的方式下,在该组件下建立一个包,就叫alone包吧~,然后在该包下创建AndroidManifests.xml文件,我的建议是直接将app组件下的AndroidManifests.xml文件直接拷贝过来,然后稍微修改下,像下面这样:

    lib_chat manifests文件
    这里大概能够理解为什么需要将res文件全部移动到common组件中去了吧,不然的app组件和chat组件是没有相互依赖的,chat组件就不能够使用图片、文字等资源了。

    3. 实现两种运行模式
    我们需要使项目有两种模式,一种是集成模式,一种是单独运行模式。
    首先,我们在project下的gradle.properties文件中添加代码isRunAlone=true,这个文件中可以放置项目需要使用的常量值,这句代码的意思就是定义了一个Boolean类型变量为true,就是“可单独运行”吧。
    接下来在其它组件的build.gradle文件下,将顶部apply plugin: 'com.android.library'代码修改为

     if(isRunAlone.toBoolean()) {
        apply plugin: 'com.android.application'
    }else{
        apply plugin: 'com.android.library'
    }
    

    这段代码的意思就是,通过常量值判断以哪种形式运行代码,.library就是作为第三方库使用,不可单独运行,.application就是可以作为一个应用单独运行。
    我们要求在单独运行的模式下,能够使用我们自定义的manifests文件。以此需要在buildTypes内添加以下代码:

    sourceSets {
                main {
                    if (isRunAlone.toBoolean()) {
                        manifest.srcFile 'src/main/alone/AndroidManifest.xml'
                    } else {
                        manifest.srcFile 'src/main/AndroidManifest.xml'
                        java {
                            //清除alone目录下的文件
                            exclude 'run_alone/**'
                        }
                    }
                }
            }
    

    最后贴出home组件的完整build.gradle文件代码:

    if (isRunAlone.toBoolean()) {
        apply plugin: 'com.android.application'
    } else {
        apply plugin: 'com.android.library'
    }
    
    android {
        compileSdkVersion rootProject.ext.android.compileSdkVersion
        defaultConfig {
            minSdkVersion rootProject.ext.android.minSdkVersion
            targetSdkVersion rootProject.ext.android.targetSdkVersion
            versionCode rootProject.ext.android.versionCode
            versionName rootProject.ext.android.versionName
            testInstrumentationRunner rootProject.ext.android.testInstrumentationRunner
    
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
    
            sourceSets {
                main {
                    if (isRunAlone.toBoolean()) {
                        manifest.srcFile 'src/main/alone/AndroidManifest.xml'
                    } else {
                        manifest.srcFile 'src/main/AndroidManifest.xml'
                        java {
                            //清除run_alone目录下的文件
                            exclude 'run_alone/**'
                        }
                    }
                }
            }
        }
    
    }
    
    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
        implementation rootProject.ext.dependencies.appcompat
        implementation rootProject.ext.dependencies.constraint_layout
        implementation 'com.android.support.constraint:constraint-layout:1.1.3'
        testImplementation rootProject.ext.dependencies.junit
        androidTestImplementation rootProject.ext.dependencies.runner
        androidTestImplementation rootProject.ext.dependencies.espresso_core
        
        //导入共用层组件
        implementation project(':lib_common')
    }
    

    我们可以单独运行了吗?不可以,因为我们还没有启动活动
    我们在每一个组建下创建一个活动,并在alone目录下的manifests文件中将它设置为启动活动。接下来就可以单独运行了。

    注意事项

    1. 资源名冲突
    当我们切换成集成运行模式下的时候,两个组件中资源命名相同的话,就会导致资源名冲突,系统怎么会知道你想采用哪一个xml文件呢?
    解决这个冲突也很简单,每一个组件都加上一个前缀就行了。添加代码resourcePrefix "前缀_"在该组件的build.gradle文件中的buildTypes内就行了,在你创建xml文件的时候,系统就会强制要求你给该xml文件添加前缀,否则就会编译报错。记住,不是编译器自动添加前缀,而是手动添加前缀,不添加则编译报错。

    2. 导库问题
    通过implementation 形式导入的库具有相互依赖性,举个栗子,我们在app组件下导入home、chat的组件后,在chat组件中就可以使用home组件的文件,同理在home组件中就可以使用chat组件的文件。
    但是,这个方法在导入第三方库的时候就行不通了。 在某个组件中使用implementation导入第三方库,那么就只有该组件能够使用该第三方库。那么我们就应该使用api的方式来实现第三方库导入,例如在common层gradle中加上代码api 'com.github.bumptech.glide:glide:3.7.0'导入Glide库,可以实现在其它组件中也调用Glide第三方库。
    仅仅在app组件下导入一次即可,单独将其导入其它业务组件代码贴出来:

     if (!isRunAlone.toBoolean()) {
            api project(":lib_chat")
            api project(":lib_home")
        }
    

    3. manifests注册、权限问题
    除了app、common组件,其它业务逻辑组件我们都应该具有两张表。但是每一次我们生成一个活动的时候,编译器只会在一张表上面去注册活动,因此一定要记住,我们需要手动在另外一张表上面注册活动。还有就是权限问题,一般我们只需要在common层的manifests文件中将所有权限都申明就可以了,不然的话,你还需要在业务组件上去申明两次权限(两张表)。

    4. 签名配置
    由于需要第三方平台的使用,需要我们提供应用的签名,我们要统一我们APK的签名。这里说一种最常用的自动签名的方式。在我们手动打包一次APK之后,生成了.key文件,接下来直接代码啦:

    //在build.gradle的android 内
    signingConfigs {
            //签名配置要在buildtypes之前
            //签名文件放在build.gradle同级目录
            config {
                //填写自己的key文件的相对路径
                storeFile file("./key.jks")
                storePassword "123456"
                keyAlias "123456"
                keyPassword "123456"
            }
        }
        buildTypes {
            release {
                //使用签名
                signingConfig signingConfigs.config
                //混淆
                minifyEnabled true
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
            debug {
                signingConfig signingConfigs.config
                minifyEnabled true
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    
    我们需要在其它的组件下也添加这段代码,当然有快捷方式,就是在Android Studio的Project Structure中的signing去设置,它会自动在build.gradle中生成相应代码。 Project Structure

    组件化的介绍暂时就到这儿了,肯定是有许多地方是没有讲到的,就靠自己慢慢摸索啦~
    下一篇文章讲路由,Android 讲解组件化-路由框架(2)

    笔者水平有限,有写得不好的地方,请大胆指出~
    转载请注明出处~

    相关文章

      网友评论

          本文标题:Android 浅解组件化-路由框架(1)

          本文链接:https://www.haomeiwen.com/subject/nldepqtx.html