Android组件化设计

摘要:随着app迭代,以及功能需求的升级,项目中的冗余代码量增多,代码各板块间的耦合加强,不利于升级以及测试,所以开始了组建化的设计。android的组件化基于module的两种属性application属性,module可以作为独立的app运行apply plugin: ‘com.android.app

随着app迭代,以及功能需求的升级,项目中的冗余代码量增多,代码各板块间的耦合加强,不利于升级以及测试,所以开始了组建化的设计。

android的组件化基于module的两种属性
application属性,module可以作为独立的app运行
apply plugin: ‘com.android.application’
library属性,module不可独立运行,作为依赖库文件
apply plugin: ‘com.android.library’
通过控制module的此属性可以间module在app以及依赖库之间进行切换,此属性在build.gradle文件中。
而且项目的gradle文件是可以公用的,所以可以新建一个config.gradle文件进行对module以及少量依赖进行配置。

/** *  全局统一配置文件 */ext {    //true 每个业务Module可以单独开发    //false 每个业务Module以lib的方式运行    //修改之后需要Sync方可生效    isModule = false    //版本号    versions = [            applicationId           : "com.example.bwq.moduletest",        //应用ID            versionCode             : 1,                    //版本号            versionName             : "1.0.0",              //版本名称            compileSdkVersion       : 28,            buildToolsVersion       : "27.0.3",            minSdkVersion           : 16,            targetSdkVersion        : 28,            androidSupportSdkVersion: "28.+",            constraintLayoutVersion : "1.1.3",            runnerVersion           : "1.0.2",            espressoVersion         : "3.0.2",            junitVersion            : "4.12",            multidexVersion         : "1.0.2",            butterknifeVersion      : "8.8.1",            arouterApiVersion       : "1.4.0",            arouterCompilerVersion  : "1.2.1",            arouterannotationVersion: "1.0.4",            recyclerview            : "28.+",            cardview                : "28.+",            //三方依赖的版本控制    ]    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"]}",                    recyclerview          : "com.android.support:recyclerview-v7:${versions["recyclerview"]}",                    cardview              : "com.android.support:cardview-v7:${versions["cardview"]}",                    //三方依赖的库地址    ]}

其中isModule为控制module为组建模式还是app模式的开关
因而组建module的属性可通过开关来判断,在组建build.gradle文件开头设置为如下:

if (Boolean.valueOf(rootProject.ext.isModule)) {    apply plugin: 'com.android.application'} else {    apply plugin: 'com.android.library'}

在组建化中我将app分为三层,
第一层:app层
app入口,初始化页面,以及主页通过在主页viewpager中增加fragment使其成为正常app的主页。
第二层:组建层
将项目按功能划分为各个组建,如登录组建,首页组建,我的组建等,组建间通过路由的方式跳转以及传递数据。
第三层:基础层
项目基础层,公用控件,公用的方法资源文件,网络请求方法,以及依赖库的封装都在这层进行实现。
组建层以及app层的每一个module均依赖基础层,app层依赖每一个组建层以及基础层。
基础层中将在配置文件中的依赖方法,进行依赖,基础层不需要成为app独立运行,因而无需设置application以及library的开关,依赖关键字使用api:

apply plugin: 'com.android.library'apply plugin: 'com.jakewharton.butterknife'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"        //MultiDex分包方法        multiDexEnabled true        //Arouter路由配置        javaCompileOptions {            annotationProcessorOptions {                arguments = [AROUTER_MODULE_NAME: project.getName()]                includeCompileClasspath = true            }        }    }    compileOptions {        sourceCompatibility JavaVersion.VERSION_1_8        targetCompatibility JavaVersion.VERSION_1_8    }    buildTypes {        release {            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }    }}dependencies {    implementation fileTree(include: ['*.jar'], dir: 'libs')    //把implementation 用api代替,它是对外部公开的, 所有其余的module就不需要增加该依赖    api rootProject.ext.dependencies["appcompat_v7"]    api rootProject.ext.dependencies["constraint_layout"]    api rootProject.ext.dependencies["cardview-v7"]    api rootProject.ext.dependencies["recyclerview-v7"]    api rootProject.ext.dependencies["support-v4"]    api rootProject.ext.dependencies["design"]    api rootProject.ext.dependencies["support_annotations"]    //MultiDex分包方法    api rootProject.ext.dependencies["multidex"]    //黄油刀    annotationProcessor rootProject.ext.dependencies["butterknife_compiler"]    api rootProject.ext.dependencies["butterknife"]    //Arouter路由    annotationProcessor rootProject.ext.dependencies["arouter_compiler"]    api rootProject.ext.dependencies["arouter_api"]    api rootProject.ext.dependencies["arouter_annotation"]    api rootProject.ext.dependencies["recyclerview"]    api rootProject.ext.dependencies["cardview"]    }

第二层中因每个组建均需要成为独立app进行测试以及开发,因而,他的manifest文件需要两套,一套为普通library的没有app入口,一套为application的有app入口的文件。
新建module,选择phone&table module,建立标准app module,main包下新建路径manifest放置module作为app时的manifest文件


project显示模式下main文件夹

黄色框为新建文件夹以及新建文件:
manifest配置为基础app配置

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.bwq.main">    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:roundIcon="@mipmap/ic_launcher_round"        android:supportsRtl="true"        android:theme="@style/MyAppTheme"        android:name=".debug.MainApplication">        <activity android:name=".debug.MainActivity">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>

红色框中的manifest文件为library时的

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.bwq.main">    <application>        <activity android:name=".debug.MainActivity"/>    </application></manifest>

在java中新建debug包,放置少量作为独立app时的配置,如继承自基础层的Application类,假如组建入口为fragment时展现fragment的activity,之后在当前module的builde.gradle中配置

if (Boolean.valueOf(rootProject.ext.isModule)) {    apply plugin: 'com.android.application'} else {    apply plugin: 'com.android.library'}apply plugin: 'com.jakewharton.butterknife'android {    compileSdkVersion rootProject.ext.versions.compileSdkVersion    buildToolsVersion rootProject.ext.versions.buildToolsVersion    defaultConfig {        if (Boolean.valueOf(rootProject.ext.isModule))            applicationId rootProject.ext.versions.applicationId        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"        //MultiDex分包方法        multiDexEnabled true        //Arouter路由配置        javaCompileOptions {            annotationProcessorOptions {                arguments = [AROUTER_MODULE_NAME: project.getName()]                includeCompileClasspath = true            }        }    }    compileOptions {        sourceCompatibility JavaVersion.VERSION_1_8        targetCompatibility JavaVersion.VERSION_1_8    }    buildTypes {        release {            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }    }    sourceSets {        //配置当前module作为app和作为library时的manifest文件以及作为library时所需要忽略的文件        main {            if (Boolean.valueOf(rootProject.ext.isModule)) {                manifest.srcFile 'src/main/manifest/AndroidManifest.xml'            } else {                manifest.srcFile 'src/main/AndroidManifest.xml'                java {                    exclude '*debug/**'                    exclude '*manifest/**'                }            }        }    }}dependencies {    implementation fileTree(dir: 'libs', include: ['*.jar'])    //butterKnife    implementation 'com.android.support.constraint:constraint-layout:1.1.3'    annotationProcessor rootProject.ext.dependencies["butterknife_compiler"]    annotationProcessor rootProject.ext.dependencies["arouter_compiler"]    api project(':basis_library')}

为了方便组建间的跳转,在基础层中BaseApplication类中初始化路由,BaseApplication为所有组建以及app的Application类的基类。

/**     * 初始化ARouter     */    public void initARouter() {        if (BuildConfig.DEBUG) {            ARouter.openLog();            ARouter.openDebug();        }        ARouter.init(instance);    }

添加组建化后的跳转工具类

public class ARouterUtils {    /**     * 根据path返回Fragment     *     * @param path path     * @return fragment     */    public static BaseLazyFragment getLazyFragment(String path) {        return (BaseLazyFragment) ARouter.getInstance()                .build(path)                .navigation();    }    public static BaseFragment getFragment(String path) {        return (BaseFragment) ARouter.getInstance()                .build(path)                .navigation();    }    /**     * 根据path返回Activity     *     * @param path path     * @return Activity     */    public static BaseActivity getActivity(String path) {        return (BaseActivity) ARouter.getInstance()                .build(path)                .navigation();    }    /**     * 根据path返回FragmentActivity     *     * @param path path     * @return FragmentActivity     */    public static BaseFragmentActivity getFragmentActivity(String path) {        return (BaseFragmentActivity) ARouter.getInstance()                .build(path)                .navigation();    }}

路由跳转URL地址

/** * 功能板块入口 */public interface ARouterConfig {    /**     * 登录页面     */    String LOGIN = "/login/LoginActivity";    /**     * main     */    String MAIN = "/main/MainFragment";    /**     * mine     */    String MINE = "/mine/MineFragment";}

app层:
builde.gradle配置:

apply plugin: 'com.android.application'apply plugin: 'com.jakewharton.butterknife'android {    compileSdkVersion rootProject.ext.versions.compileSdkVersion    buildToolsVersion rootProject.ext.versions.buildToolsVersion    defaultConfig {        applicationId rootProject.ext.versions.applicationId        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"        //MultiDex分包方法        multiDexEnabled true        //Arouter路由配置        javaCompileOptions {            annotationProcessorOptions {                arguments = [AROUTER_MODULE_NAME: project.getName()]                includeCompileClasspath = true            }        }    }    compileOptions {        sourceCompatibility JavaVersion.VERSION_1_8        targetCompatibility JavaVersion.VERSION_1_8    }    buildTypes {        release {            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }    }}dependencies {    implementation fileTree(dir: 'libs', include: ['*.jar'])    implementation 'com.android.support.constraint:constraint-layout:1.1.3'    annotationProcessor rootProject.ext.dependencies["butterknife_compiler"]    annotationProcessor rootProject.ext.dependencies["arouter_compiler"]    api project(':basis_library')    if (!Boolean.valueOf(rootProject.ext.isModule)) {        api project(':main')        api project(':login')        api project(':mine')    }}

至此,组建化方案完成。

最后说少量注意的问题,各层的依赖关键字需要使用api,不同组建间的资源文件因为在组合后可能会有冲突,各组建间的资源文件建议以组建名开头,如login_back

  • 全部评论(0)
最新发布的资讯信息
【系统环境|】通义万相wan2.2本地部署要求有哪些?通义万相wan2.2怎么本地部署(2025-10-21 04:05)
【系统环境|】Vue3 页面卡顿严重?7 个实战技巧让渲染速度飙升 80%!(2025-10-21 04:01)
【系统环境|】前端小白 2 周 Vue3+TS+NaiveUI 学习计划大纲(2025-10-21 04:00)
【系统环境|】Vue3 入门指南: 深入理解 Setup 函数(2025-10-21 03:59)
【系统环境|】2024前端面试真题之—VUE篇(2025-10-21 03:58)
【系统环境|】搞懂Vue3的toRefs与toRef:响应式对象的解构(2025-10-21 03:55)
【系统环境|】三.不定词副词的用法(2025-10-21 03:53)
【系统环境|】歌曲中汉字的信息量真的是吊打英语(2025-10-21 03:52)
【系统环境|】跟着《肖申克的救赎》学英语(002)--安迪法庭受审(2025-10-21 03:52)
【系统环境|】词根词缀-前缀1-27: de-(2025-10-21 03:50)
手机二维码手机访问领取大礼包
返回顶部