Inicio rápido y uso de la creación de componentes / modularización: la creación de componentes se realiza mediante la gestión de gradle en Android; y con ARouter, salta y cambia a voluntad

Prefacio : Este artículo modular y en componentes se presentará en dos artículos. Algunas personas pueden pensar que ya hay artículos en Internet, entonces, ¿por qué escribirlos? Primero: para registrar la propia normalidad, se puede considerar como una nota. Segundo: Aunque hay buenos artículos en Internet, recientemente leí un artículo que tiene más de 150 me gusta, pero la introducción es vaga y se omiten muchos puntos de conocimiento. El objetivo de este artículo es permitirle comenzar rápidamente, comprender y utilizar.

Esta explicación modular / de componentes se divide en 2 artículos (primero debe comprender ARouter o un marco de enrutamiento de terceros):
1. El uso básico del marco de enrutamiento de Alibaba ARouter
2. La componenteización de Android a través de la administración de gradle; y cooperar con ARouter , Salta y cambia a voluntad

De hecho, antes de saber acerca de la modularidad / componentes, pensé que era de muy alta gama y ni siquiera me atrevía a tocarlo. Tal vez sea porque los blogs de otras personas son muy sofisticados. De hecho, después del contacto, descubrí que en realidad se logró a través de la administración de Gradle. La gama alta es solo la comunicación entre módulos, pero ARouter nos ha ayudado a resolverlo todo. Sígueme paso a paso. Comprendan juntos, agreguen esta demostración al final.

Antes del comienzo de este artículo
, permítanme hablar sobre un poco de conocimiento : un módulo presenta el módulo B y el módulo B presenta el módulo C. Si se usa el método de implementación, entonces C es invisible para A; y se usa el método api C. Se puede acceder mediante A. De la misma manera, la conclusión de reemplazar C con bibliotecas de código abierto, por lo que los archivos, archivos aar y archivos jar también es aplicable.
Si es un paquete jar, si la clase padre quiere introducir la subclase, debe agregar fuerza de camino como: dirs'libs ',' ... / moduleB / libs '. La clase principal introduce las bibliotecas en moduleB

1. La demostración y el efecto final de este artículo

Esto es lo mismo que la mayoría en línea, tomando WeChat como ejemplo. Divida WeChat en 4 módulos: inicio, chat, búsqueda, mío.

  • Para la aplicación del programa principal, estos 4 módulos son su biblioteca. Genere nuestra aplicación principal después de ejecutar la aplicación;

Al cambiar la configuración de gradle, podemos ejecutar por separado el módulo de inicio, el módulo de chat, el módulo de búsqueda y el módulo de mina como una aplicación. La ventaja de esta modularidad es el desacoplamiento. Los módulos son desarrollados por desarrolladores sin que se afecten entre sí, y la gestión del código no entrará en conflicto, etc.

El resultado final es este, aquí solo escribí el módulo de inicio, el módulo de chat. De hecho, los otros dos son iguales. (Y este es un proyecto, generado por gradle)

Estas aplicaciones se pueden generar simplemente cambiando la configuración de gradle.

Aplicación completa home_module ejecuta la aplicación por separado chat_module ejecutar la aplicación por separado
Desde la capa más externa

2. Cree un nuevo proyecto y use config.gradle para administrar el número de versión para evitar conflictos de versiones

Cree un nuevo proyecto, mi proyecto aquí es CatModuleStu, en el directorio del proyecto build.gradle, un nuevo config.gradle. Si no es así, copie el proyecto build.gradle directamente y cambie el nombre. El contenido interno se cambia de acuerdo con build.gradle en nuestra aplicación. El build.gradle en la aplicación es el siguiente:

apply plugin: 'com.android.application'

android {
    
    
    compileSdkVersion 28
    defaultConfig {
    
    
        applicationId "com.lihang.catmodulestu"
        minSdkVersion 22
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

    }
    buildTypes {
    
    
        release {
    
    
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    
    
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}


Significa expresar estas referencias específicas con constantes, y cada módulo usa estas constantes , por lo que nuestro confing.gradle es el siguiente:

ext {
    
    
    //这里是配置开关。是否需要单独运行。注意,这里只能打开一个。因为一次只能运行一个。。
    //true 表示需要单独运行。false表示不需要单独运行。
    isNeedHomeModule = false
    isNeedChatModule = false
    isNeedFindModule = false
    isNeedMineModule = false

    android = [
            compileSdkVersion: 28,
            buildToolsVersion: "28.0.0",
            minSdkVersion    : 22,
            targetSdkVersion : 28,
            versionCode      : 1,
            versionName      : "1.0.0",
            applicationId    : "com.lihang.catmodulestu",
            applicationHomeId: "com.lihang.homemodule",
            applicationChatId: "com.lihang.chatmodule"
    ]

    //这个对依赖库版本version的管理,就更加细致化了
    version = [
            androidSupportSdkVersion: "28.0.0"
    ]

    //系统依赖
    dependencies = [
            "support:appcompat-v7": "com.android.support:appcompat-v7:${version["androidSupportSdkVersion"]}",
            "test:runner"         : 'com.android.support.test:runner:1.0.2',
            "test.espresso"       : 'com.android.support.test.espresso:espresso-core:3.0.2',
            "junit"               : 'junit:junit:4.12'
    ]

    //第三方库(请原谅我的英语)
    //这样依赖库看起来比较清晰(dependencies : 代表系统依赖库;thridencies代表第三依赖库)
    thridencies = [
            "butterknife"         : 'com.jakewharton:butterknife:8.8.1',
            "butterknife-compiler": 'com.jakewharton:butterknife-compiler:8.8.1',
            "arouter-compiler"    : 'com.alibaba:arouter-compiler:1.1.4',
            "arouter"             : 'com.alibaba:arouter-api:1.3.1',
    ]
}


Después de escribirlos, en la parte superior de nuestro proyecto build.gradle, cite nuestro config.gradle :
apply from: "config.gradle"


Después de hacer esto, mire el build.gradle de nuestra aplicación

apply plugin: 'com.android.application'

android {
    
    
    compileSdkVersion rootProject.ext.android["compileSdkVersion"]
    defaultConfig {
    
    
        applicationId rootProject.ext.android["applicationId"]
        minSdkVersion rootProject.ext.android["minSdkVersion"]
        targetSdkVersion rootProject.ext.android["targetSdkVersion"]
        versionCode rootProject.ext.android["versionCode"]
        versionName rootProject.ext.android["versionName"]
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
    
    
        release {
    
    
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    
    
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation rootProject.ext.dependencies["support:appcompat-v7"]
    testImplementation rootProject.ext.dependencies["junit"]
    androidTestImplementation rootProject.ext.dependencies["test:runner"]
    androidTestImplementation rootProject.ext.dependencies["test.espresso"]
}

3. Cree un nuevo módulo base.

Cree un nuevo módulo base, coloque las solicitudes de red de uso común, carga de imágenes, lo que significa que se colocan las cosas compartidas por otros módulos. Incluidos los archivos de recursos compartidos, BaseActivity, BaseFragment y la aplicación también se colocan aquí, el uso de ARouter mencionado en el artículo anterior, también se coloca la inicialización Esta. Este módulo base se utiliza completamente como biblioteca. Referenciado por otros módulos y aplicaciones. Pero hay dos trampas aquí :
1. Cuando se introduce ARouter, agregue bajo la etiqueta de dependencias en build.gradle de baseModule:

api rootProject.ext.thridencies["arouter"]
annotationProcessor rootProject.ext.thridencies["arouter-compiler"]

Agregar a la etiqueta defaultConfig de Android

javaCompileOptions {
    
    
            annotationProcessorOptions {
    
    
                arguments = [moduleName: project.getName()]
            }
        }

Cuando otros módulos se refieren a baseModule, también se deben agregar javaCompileOptions bajo la etiqueta defaultConfig. Al mismo tiempo, se deben introducir las siguientes dependencias, ¡correcto! Lo leíste bien. Si no se agrega, no tendrá éxito. :

annotationProcessor rootProject.ext.thridencies["arouter-compiler"]

2. Aquí se utiliza un cuchillo de mantequilla . Por ejemplo, después de que baseModule haga referencia a butterknife, cuando otros módulos hagan referencia a baseModule, aparecerá un error o mensaje de error: el elemento debe ser una constante. Entonces Butterknife ofrece oficialmente una solución, utilizando R2. Pero cuando el módulo se cambia para ejecutarse como una aplicación, R2 informará un error, lo que significa que R2 debe cambiarse a R cuando se use como una aplicación. Si usa R2 en su módulo, debe cambiarlo a R en este momento. Por lo tanto, no se recomienda que baseModule haga referencia a la navaja. Si hay una buena solución, ¡hágamelo saber! !


4. Crea un nuevo homeModule

Primero mire el build.gradle de homeModule:

//这里就用到了config的配置isNeedHomeModule
//开头设置,如果打开开光,当成项目运行,否则当成library引用
if (isNeedHomeModule.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"]
        if (isNeedHomeModule.toBoolean()) {
    
    
            //同时在conifg.gradle配置上homeModule的包名。
            //当作为application运行的时候,给他配置上独立的包名
            applicationId rootProject.ext.android["applicationHomeId"]
        }
        versionCode rootProject.ext.android["versionCode"]
        versionName rootProject.ext.android["versionName"]
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        //ARouter的使用记得要加哦
        javaCompileOptions {
    
    
            annotationProcessorOptions {
    
    
                arguments = [moduleName: project.getName()]
            }
        }
    }

    buildTypes {
    
    
        release {
    
    
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    sourceSets {
    
    
        main {
    
    
            if (isNeedHomeModule.toBoolean()) {
    
    
                //这里目前的做法是2套AndroidManifest,作为app运行的时候要指定启动页
                manifest.srcFile 'src/main/buildApp/AndroidManifest.xml'
            } else {
    
    
                manifest.srcFile 'src/main/buildModule/AndroidManifest.xml'
            }
        }
    }

}

dependencies {
    
    
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation rootProject.ext.dependencies["support:appcompat-v7"]
    testImplementation rootProject.ext.dependencies["junit"]
    androidTestImplementation rootProject.ext.dependencies["test:runner"]
    androidTestImplementation rootProject.ext.dependencies["test.espresso"]
    implementation project(':baseModule')
    annotationProcessor rootProject.ext.thridencies["arouter-compiler"]
}

En el código anterior, podemos ver que hay 3 puntos a tener en cuenta :

  • 1. Juzgue si se ejecutará como una aplicación o una biblioteca a través de isNeedHomeModule
if (isNeedHomeModule.toBoolean()) {
    
    
    apply plugin: 'com.android.application'
} else {
    
    
    apply plugin: 'com.android.library'
}

  • 2. Juzgue por isNeedHomeModule, si se ejecuta como una aplicación, configure appId para ello
    if (isNeedHomeModule.toBoolean()) {
    
    
            applicationId rootProject.ext.android["applicationHomeId"]
        }

  • 3. A juzgar por isNeedHomeModule, configure dos AndroidManifests, uno con una página de inicio y el otro sin una página de inicio.
if (isNeedHomeModule.toBoolean()) {
    
    
                //这里目前的做法是2套AndroidManifest,作为app运行的时候要指定启动页
                manifest.srcFile 'src/main/buildApp/AndroidManifest.xml'
            } else {
    
    
                manifest.srcFile 'src/main/buildModule/AndroidManifest.xml'
            }

Los dos AndroidManifests no se publican aquí y puede verlos usted mismo a través de mi demostración. De hecho, es para especificar una actividad en la página de inicio. Para mayor claridad de la demostración, creé una SelectHomeActivity, y luego el módulo homeModule, y todas las configuraciones de actividad utilizadas se colocan aquí. Si se usa como biblioteca, ponga toda la configuración aquí. Cuando lo cita la aplicación principal, automáticamente vendrá aquí para encontrarlo, por lo que no tenemos que preocuparnos por eso.

Después de hacer esto, cuando homeModule se ejecuta como una aplicación, nuestra aplicación principal, por supuesto, también debe juzgar, y no se puede hacer referencia a homeModule. Build.gradle es el siguiente:

dependencies {
    
    
   ... //省略部分代码,便于理解
    if (!isNeedHomeModule.toBoolean()) {
    
    
        implementation project(':homeModule')
    }
}

Después de hacer esto, habrá terminado. Otros módulos tienen la misma configuración que este. Al cambiar la configuración de isNeedHomeModule en config.gradle, los módulos se pueden ejecutar por separado.

5. Cuando se utiliza cada clase de módulo en la aplicación principal.

Como referencia de la biblioteca. Por ejemplo, mi demostración es cambiar haciendo clic en el botón de abajo. Debido a que usamos ARouter, puede ser así (por supuesto, se cita aquí, también puede usar el nombre de la clase directamente):

//这样就生成了一个HomeFragment的实例
HomeFragemnt fragment_one = (HomeFragemnt) ARouter.getInstance().build(Constance.FRAGMENT_HOME_PATH).withString("wo", "1").navigation();

Conclusión: Hasta ahora, sobre la modularización y la creación de componentes en Android, eso es todo.

Aquí hablaré sobre mi propio entendimiento:
Modularización: así, dividimos nuestro WeChat en 4 módulos. Lo entiendo como modularidad.

Componentización: al igual que el módulo base aquí, o el diálogo o ventana emergente que encapsula. Por otro ejemplo, algunos efectos del tercero en línea que utiliza. Lo entiendo como modularidad. Al igual que la modularidad, es para desacoplar.

Tus me gusta son mi mayor motivación, dirección de github

Supongo que te gusta

Origin blog.csdn.net/leol_2/article/details/100700132
Recomendado
Clasificación