android 组件化重构项目

作者: 刘景昌 | 来源:发表于2019-07-18 17:00 被阅读23次

    1.为什么要组件化

    (1)耦合严重:单一工程的业务之间耦合度太高,牵一发而动全身
    (2)编译时间慢: 对工程的任何更改都必须编译整个工程
    (3)测试麻烦:功能测试和系统测试每次都要进行
    (4)开发效率不高:共同开发时容易产生冲突
    (5)不够灵活:不能灵活的对业务模块进行配置和组装;

    2.组件化介绍

    组件化就是一个完整的app拆分成多个子模块每个子模块可以独立的编译或者运行,可以任意组合成另一个新的app或者模块,每个模块之间几部想不依赖有可以相互交互 。
    组件化的基本组成:
    (1)app壳工程:就是一个空的工程,负责打包apk没有具体的业务功能
    (2)业务组件:每个业务模块单独出来可以形成一个独立的工程
    (3)common组件:为每个业务模块提供公共的组件 如 工具类 网络类的封装
    (4)三方组件:把一系列的三方类的功能集合在一起形成的组件 如 微信支付+支付宝支付 +其他三方支付= 支付组件

    3.组件化实施流程

    由于是之前自己独立开发的一个比较小的工程,所有逻辑也是自己写的所以实施组件化起来还是比较方便的,因为是重构以前的工程而不是重写 所以需要一步步的进行 从开始学习开始 到最后的组件化完成 差不多一周时间 。
    (1)拆解工程 提取commonLibrary模块
    我们在提取过程中要做的事情

    1.为了保证每个业务组件的版本的统一个模块是否模块化的开启

    添加统一的引用的gradle config.gradle 在这里吧原来使用的引用和版本都添加进来

    /**
     *  全局统一配置文件
     */
    ext {
        //true 每个业务Module可以单独开发
        //false 每个业务Module以lib的方式运行
        //修改之后需要Sync方可生效
        isModule = false
        //版本号
        versions = [
                applicationId           : "com.example.componentapplication",        //应用ID
                versionCode             : 1,                    //版本号
                versionName             : "1.0.0",              //版本名称
    
                compileSdkVersion       : 28,
                buildToolsVersion       : "28.0.3",
                minSdkVersion           : 17,
                targetSdkVersion        : 23,
    
                androidSupportSdkVersion: "28.0.0",
                constraintLayoutVersion : "1.1.1",
                runnerVersion           : "1.0.1",
                espressoVersion         : "3.0.1",
                junitVersion            : "4.12",
                annotationsVersion      : "24.0.0",
                javaSDKVersion          : 1.8,//javaSDK版本
    
                multidexVersion         : "1.0.2",
                butterknifeVersion      : "9.0.0",
    
                arouterApiVersion       : "1.4.0",
                arouterCompilerVersion  : "1.2.1",
                arouterannotationVersion: "1.0.4",
                gsonVersion             :"2.4",
                //rxjava 家族和网络请求
                rxjavaVersion           :"2.1.6",
                rxandroidVersion        :"2.0.1",
                retrofitVersion         :"2.3.0",
                convertergsonVersion    :"2.2.0",
                rxjava2adapterVersion   :"2.3.0",
                logginginterceptorVersion:"3.7.0",
                takephotolibraryVersion :"4.0.3" ,
                glideVersion            :"3.8.0",
                baservadapterVersion    :"3.0.3",
                flowlayoutVersion       :"1.0.3",
                permissionVersion       :"1.1.0",
                autosizeVersion         :"1.1.2"
    
        ]
        dependencies = [
                "appcompat_v7"        : "com.android.support:appcompat-v7:${versions["androidSupportSdkVersion"]}",
                "constraint_layout"   : "com.android.support.constraint:constraint-layout:${versions["constraintLayoutVersion"]}",
                "runner"              : "com.android.support.test:runner:${versions["runnerVersion"]}",
                "espresso_core"       : "com.android.support.test.espresso:espresso-core:${versions["espressoVersion"]}",
                "junit"               : "junit:junit:${versions["junitVersion"]}",
                "support_annotations" : "com.android.support:support-annotations:${versions["annotationsVersion"]}",
                "design"              : "com.android.support:design:${versions["androidSupportSdkVersion"]}",
                "support-v4"          : "com.android.support:support-v4:${versions["androidSupportSdkVersion"]}",
                "cardview-v7"         : "com.android.support:cardview-v7:${versions["androidSupportSdkVersion"]}",
                "recyclerview-v7"     : "com.android.support:recyclerview-v7:${versions["androidSupportSdkVersion"]}",
                //方法数超过65535解决方法64K MultiDex分包方法
                "multidex"            : "com.android.support:multidex:${versions["multidexVersion"]}",
    
                //路由
                "arouter_api"         : "com.alibaba:arouter-api:${versions["arouterApiVersion"]}",
                "arouter_compiler"    : "com.alibaba:arouter-compiler:${versions["arouterCompilerVersion"]}",
                "arouter_annotation"  : "com.alibaba:arouter-annotation:${versions["arouterannotationVersion"]}",
    
    
                "butterknife_compiler": "com.jakewharton:butterknife-compiler:${versions["butterknifeVersion"]}",
                "butterknife"         : "com.jakewharton:butterknife:${versions["butterknifeVersion"]}",
    
                "gson"                : "com.google.code.gson:gson:${versions["gsonVersion"]}",
                "rxjava"              : "io.reactivex.rxjava2:rxjava:${versions["rxjavaVersion"]}",
                "rxandroid"           : "io.reactivex.rxjava2:rxandroid:${versions["rxandroidVersion"]}",
                "retrofit"            : "com.squareup.retrofit2:retrofit:${versions["retrofitVersion"]}",
                "convertergson"       : "com.squareup.retrofit2:converter-gson:${versions["convertergsonVersion"]}",
                "rxjava2adapter"      : "com.squareup.retrofit2:adapter-rxjava2:${versions["rxjava2adapterVersion"]}",
                "logginginterceptor"  : "com.squareup.okhttp3:logging-interceptor:${versions["logginginterceptorVersion"]}",
    
                "glide"               : "com.github.bumptech.glide:glide:${versions["glideVersion"]}",
                "baservadapte"        : "com.zhy:base-rvadapter:${versions["baservadapterVersion"]}",
                "flowlayout"          : "com.zhy:flowlayout-lib:${versions["flowlayoutVersion"]}",
                "permission"          : "com.yanzhenjie:permission:${versions["permissionVersion"]}",
        ]
    
    }
    

    然后一定要记得 在application 的 gadle中添加

    apply from: "config.gradle"
    

    否则会报 类似这种的错误

    ERROR: Cannot get property 'versions' on extra properties extension as it does not exist
    

    然后就是修改commonlibrary的gradle

    apply plugin: 'com.android.library'
    
    android {
        compileSdkVersion rootProject.ext.versions.compileSdkVersion
        buildToolsVersion rootProject.ext.versions.buildToolsVersion
        defaultConfig {
            minSdkVersion rootProject.ext.versions.minSdkVersion
            targetSdkVersion rootProject.ext.versions.targetSdkVersion
            versionCode rootProject.ext.versions.versionCode
            versionName rootProject.ext.versions.versionName
    
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
            //Arouter路由配置
            javaCompileOptions {
                annotationProcessorOptions {
                    arguments = [AROUTER_MODULE_NAME: project.getName()]
                    includeCompileClasspath = true
                }
            }
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
        compileOptions {
            sourceCompatibility = '1.8'
            targetCompatibility = '1.8'
        }
        compileOptions {
            targetCompatibility rootProject.ext.versions.javaSDKVersion
            sourceCompatibility rootProject.ext.versions.javaSDKVersion
        }
    }
    
    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
        //把implementation 用api代替,它是对外部公开的, 所有其他的module就不需要添加该依赖
        api rootProject.ext.dependencies["support_annotations"]
        api rootProject.ext.dependencies["junit"]
    
        //MultiDex分包方法
        api rootProject.ext.dependencies["multidex"]
    
        //Arouter路由
        annotationProcessor rootProject.ext.dependencies["arouter_compiler"]
        api rootProject.ext.dependencies["arouter_api"]
        api rootProject.ext.dependencies["arouter_annotation"]
        //解析
        api rootProject.ext.dependencies["gson"]
        //rxjava和网络
        api rootProject.ext.dependencies["rxjava"]
        api rootProject.ext.dependencies["rxandroid"]
        api rootProject.ext.dependencies["retrofit"]
        api rootProject.ext.dependencies["convertergson"]
        api rootProject.ext.dependencies["rxjava2adapter"]
        api rootProject.ext.dependencies["logginginterceptor"]
        //图片加载
        api rootProject.ext.dependencies["glide"]
        //黄油刀
        annotationProcessor rootProject.ext.dependencies["butterknife_compiler"]
        api rootProject.ext.dependencies["butterknife"]
        //权限
        api rootProject.ext.dependencies["permission"]
        api 'com.flyco.tablayout:FlycoTabLayout_Lib:2.1.2@aar'
        implementation project(path: ':uilibrary')
    
    }
    

    把原来自己原来封装的baseActivity 、网络等一些内容移动进来


    image.png

    这样我们对commonLib的封装就完成了

    2.业务模块的封装

    每个不同的app都有着自己不同封装,这个是需要根据具体的逻辑来的 就让我们先看一下原理的界面来抽出不同的业务模块。
    先看具体界面


    image.png

    最终一共分为五个模块、
    home:入口+首页模块
    answer:答题测试模块
    shop:积分商城模块
    me:个人中心模块
    commonActiivty:需要在四个模块中都需要用到的模块 如登录注册 等
    业务模块遇到的问题

    1.butterknife问题

    application的gradle中添加 classpath 'com.jakewharton:butterknife-gradle-plugin:9.0.0'
    需要在每个模块的gradle中添加

    apply plugin: 'com.jakewharton.butterknife
    dependencies {
        annotationProcessor rootProject.ext.dependencies["butterknife_compiler"]
    }
    
    2.Arouter配置问题

    一定要早每一个module中都要配置

      javaCompileOptions {
                annotationProcessorOptions {
                    arguments = [AROUTER_MODULE_NAME: project.getName()]
                    includeCompileClasspath = true
                }
            }
    
    3.application和library转换问题

    在module的gradle中添加根据config中多的isModule判断是集成模式还是单个运行模式
    if (Boolean.valueOf(rootProject.ext.isModule)) {
    apply plugin: 'com.android.application'
    } else {
    apply plugin: 'com.android.library'
    }

    4.资源文件问题

    在给资源文件命名的时候一定要以当前的module为前缀

    5.不同xml问题

    根据模式判断加载那个xml
    在module/AndroidManifest.xml'下面要记得配置入口啊
    sourceSets {
    main {
    if (Boolean.valueOf(rootProject.ext.isModule)) {
    manifest.srcFile 'src/main/module/AndroidManifest.xml'
    } else {
    manifest.srcFile 'src/main/AndroidManifest.xml'
    java {
    //排除java/debug文件夹下的所有文件
    exclude '*module'
    }
    }
    }
    最后上传组件化demo: https://github.com/525642022/ComponentApplication

    相关文章

      网友评论

        本文标题:android 组件化重构项目

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