Android 组件化实战一: Gradle基础语法

前言

Android 组件化系列文章旨在彻底掌握组件化的原理,从0到1搭建一个自定义的组件化框架。万丈高楼平地起,本文主要介绍组件化过程中项目部署涉及的Gradle基本语法。

打印信息

// 在app/build.gradle文件中
println("hello world!")
println"hello world!"
println'hello world!'
效果一样:hello world!
println 666
结果:666

变量的使用方式

在工程根目录新建文件gradle文件config.gradle,可以把公用的信息,可扩展的信息加入进来,放到ext代码块,自定义添加需要的内容。

// 添加多个自定义属性,可以通过ext代码块
ext{
	username = "xpf"
}

要想在app/build.gradle中使用该信息,首先需要将该文件配置到项目工程,在根目录添加之后,就可以使用了

//根目录下的build.gradle头部加入自定义config.gradle,相当于layout布局中加入include语法
apply from: "config.gradle"

使用方式一:直接使用

//在app/build.gradle
println username//xpf
//正确语法:${rootProject.ext.username}
println "${rootProject.ext.username}"//xpf
rootProject.ext.username = 163 //糖果语法,弱类型语言Groovy ,这里给username重新赋值了
//简化语法:"${username}"
println "${username}"//163
println '${username}'//'${username}' 要注意单引号里面是什么内容打印的就是什么内容,最好统一用双引号""

使用方式二:定义变量

//在app/build.gradle
def name = rootProject.ext.username
println "name: " + name//name: xpf
rootProject.ext.username = 163 //糖果语法,弱类型,类型可以推倒
println username //163
println "name: " + name// name: xpf

其实在组件化开发中,多个子模块的build.gradle文件中具有很多相同的属性,因此可以抽取到config.build中,子模块进行引用。

//config.gradle文件中,添加多个自定义属性,可以通过ext代码块
ext {
    //username = "xpf"
    //生产开发环境
    //false: 组件化模式,每个子模块都对应一个apk(也就是说有多个apk),可以独立运行,调试环境
    //true:集成化模式,整个项目打包成一个(只有一个)apk,子模块不能独立运行,正式环境
    isRelease = true

    //建立Map存储,对象名、key都可以自定义,groovy糖果语法,非常灵活
    androidId = [
            compileSdkVersion: 29,
            buildToolsVersion: "29.0.3",
            minSdkVersion    : 23,
            targetSdkVersion : 29,
            versionCode      : 1,
            versionName      : "1.0",
            testInstrumentationRunner: "androidx.test.runner.AndroidJUnitRunner"
    ]

    appId = [
            applicationId: "xpf.custom.router.modular_gradle"
    ]

    //生产开发环境URL
    url = [
            "debug_entrance": "https://11.22.33.44/debug",
            "release_entrance": "https://11.22.33.44./release"
    ]

    //依赖相关
    dependencies_impl = [
            appcompat: 'androidx.appcompat:appcompat:1.1.0',
            constraintlayout:'androidx.constraintlayout:constraintlayout:1.1.3',
            junit: 'junit:junit:4.12',
            test: 'androidx.test.ext:junit:1.1.1',
            espresso: 'androidx.test.espresso:espresso-core:3.2.0',
            recyclerView: 'androidx.recyclerview:recyclerview:1.1.0'
    ]
}

在子模块如app/build.gradle文件中,引用如下:

apply plugin: 'com.android.application'

// 这一段不写就是直接使用的方式,能够正常运行
// 定义变量的方式
def androidId = rootProject.ext.androidId
def appId = rootProject.ext.appId
def dependencies_impl = rootProject.ext.dependencies_impl

android {
    compileSdkVersion androidId.compileSdkVersion
    buildToolsVersion androidId.buildToolsVersion
    defaultConfig {
        applicationId appId.applicationId
        minSdkVersion androidId.minSdkVersion
        targetSdkVersion androidId.targetSdkVersion
        versionCode androidId.versionCode
        versionName androidId.versionName
        testInstrumentationRunner androidId.testInstrumentationRunner
    }
    
    buildTypes {
        debug{
            buildConfigField("String","debug_url","\"${url.debug_entrance}\"")
        }

        release {
            minifyEnabled false
            buildConfigField("String","release_url","\"${url.release_entrance}\"")
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation dependencies_impl.appcompat
    implementation dependencies_impl.constraintlayout
    testImplementation dependencies_impl.junit
    androidTestImplementation dependencies_impl.test
    androidTestImplementation dependencies_impl.espresso
    implementation dependencies_impl.recyclerView

    implementation project(':library')
}

像dependencies里面的依赖引入方式,好比Map的形式,有key, value,循环遍历引入依赖

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    //HashMap<String, String> map = new HashMap<>();
    //implementation map.get("recyclerView")
}

其实还有更简洁的写法,一行代码就可以代替上面的依赖引入

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    /*implementation dependencies_impl.appcompat
    implementation dependencies_impl.constraintlayout
    testImplementation dependencies_impl.junit
    androidTestImplementation dependencies_impl.test
    androidTestImplementation dependencies_impl.espresso
    implementation dependencies_impl.recyclerView*/

    // 最简写法
    dependencies_impl.each {k, v -> implementation v}

    implementation project(':library')
}

关于生产环境URL的配置,这里简单的介绍一下,当我们rebuild的时候,在BuildConfig中会生成对应的属性信息:

public final class BuildConfig {
  public static final boolean DEBUG = Boolean.parseBoolean("true");
  public static final String APPLICATION_ID = "xpf.custom.router.modular_gradle";
  public static final String BUILD_TYPE = "debug";
  public static final String FLAVOR = "";
  public static final int VERSION_CODE = 1;
  public static final String VERSION_NAME = "1.0";
  // Fields from build type: debug
  public static final String debug_url = "https://11.22.33.44/debug";
}

还可以根据资源,api等进行细分配置,在开发中就可以通过BuildConfig.debug_url的形式进行url的访问,类似于将url封装为常量。关于BuildConfig还可以判断当前环境,决定是否执行相关逻辑,如日志打印:

if (BuildConfig.DEBUG) {// 这段逻辑在release环境,就不会执行
    Log.d("TAG", "onCreate: ");
}

关于组件化过程中涉及的Gradle语法就先介绍到这里了,下一遍将介绍组件化过程中的具体的项目部署。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章