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語法就先介紹到這裏了,下一遍將介紹組件化過程中的具體的項目部署。

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