1. 程式人生 > >使用Gradle構建Android專案的一些自定義配置

使用Gradle構建Android專案的一些自定義配置

最近開始養成了寫部落格的習慣。。。。希望後續能寫出更高質量的文章。。

由於工作專案的需要,我往往需要一份程式碼>多份資源>多個app。
然而每個app都有自己的包名,id,微信id…等等一系列的引數,這些引數 有的需要寫在中 有的需要寫在程式碼內,寫在String.xml中又增加了不安全的因素,導致非常難封裝到一個檔案內,加上當年用Eclipse工具開發,修改包名都要兩分鐘,編譯也非常慢,有時甚至會卡死掉,真是蛋疼死了。
自從Android studio正式被推出,附帶了Gradle這強大的東西,感覺從原始社會一下穿越到了現代。
說著說著 扯遠了,簡單寫一下我在使用Gradle構建Android專案時的一些記錄或者也可以稱其為筆記的一些東西:

gradle可以定義res檔案、方法函式、配置引數,並且可在 .class檔案、Manifest檔案以及gradle自身 中被直接呼叫。

自定義配置

支援定義BuildConfig值和res的值

  • 配置:可以在節點 defaultConfig、buildType、productFlavors 中配置:
    defaultConfig {
        applicationId "wenld.moon.color"
        minSdkVersion 14
        targetSdkVersion 23
        versionCode 1
versionName 1.0 resValue "string", "main_title", "name" // 程式碼內呼叫方式: R.string maintitle buildConfigField "boolean", "IS_LOG", "true" // 程式碼內呼叫方式: BuildConfig.IS_LOG } buildTypes { release { resValue "string", "main_title", "name" buildConfigField "boolean"
, "IS_LOG", "true" signingConfig signingConfigs.release } } productFlavors { miui { resValue "string", "main_title", "name" buildConfigField "boolean", "IS_LOG", "true" } wandoujia { resValue "string", "main_title", "name" buildConfigField "boolean", "IS_LOG", "true" } }
  • 呼叫:在程式碼中通過 BuildConfig.IS_LOGR.string.main_title 呼叫即可。

Manifest檔案內容佔位符

對Manifest進行自定義配置,使用方法:

  • 在Manifest檔案中定義一個佔位符,比如以信鴿推送的Id 例子為例,${XG_V2_ACCESS_ID},這種格式.
  • 在gradle配置檔案中加替換,可以在節點 defaultConfig、buildType、productFlavors 中配置,比如:
defaultConfig {
        applicationId "wenld.moon.color"
        minSdkVersion 14
        targetSdkVersion 23
        versionCode 1
        versionName 1.0
        manifestPlaceholders = [XG_V2_ACCESS_ID: "ecs23grg652"]
    }
    buildTypes {
        release {
            manifestPlaceholders = [XG_V2_ACCESS_ID: "ecs23grg652"]
            signingConfig signingConfigs.release
        }
    }
    productFlavors {
        miui {
            manifestPlaceholders = [XG_V2_ACCESS_ID: "ecs23grg652"]
        }
        wandoujia {
            manifestPlaceholders = [XG_V2_ACCESS_ID: "ecs23grg652"]
        }
    }

同時,還可以直接在Manifest檔案中用於包名的替換,直接使用${XG_V2_ACCESS_ID}即可。

定義函式

  • 配置:如下
def packageTime() {
    return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}
  • 呼叫: ${packageTime()} 返回值: “2016-03-03”

自定義配置雖然簡單,但是功能很強大,可以擴充套件很多不同的應用場景,比如可以定義測試和正式版本的信鴿推送的ID以及多渠道打包等等,就不一一列舉了,自己去嘗試擴充套件成自己的場景吧。

簽名部分

gradle本身直接支援簽名,只需要在releas部分新增以下程式碼即可

signingConfigs {
        debug {

        }
        release {
            storeFile file("../yourapp.keystore")
            storePassword "your password"
            keyAlias "your alias"
            keyPassword "your password"
        }
    }

    buildTypes {
        debug {
            minifyEnabled false
            zipAlignEnabled false
            shrinkResources false
            signingConfig signingConfigs.debug
        }

        release {
            minifyEnabled true//混淆編譯
            zipAlignEnabled true
            //移除無用的資原始檔
            shrinkResources true
            signingConfig signingConfigs.release
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

一般填上上面的程式碼即可執行簽名,但是一般這種方式不太安全,一般建議不要在build.gradle檔案中寫上簽名檔案的密碼,這是由於build.gradle檔案一般都會整合到程式碼的版本控制中,這樣所有人都會有簽名檔案的密碼,會有後續的麻煩。
可參考:Gradle構建專案時,將敏感資訊儲存在build.gradle之外

最終

上面說明了一下 如何在gradle中自定義配置引數、呼叫方法和如何gradle引入外部檔案Gradle構建專案時,將敏感資訊儲存在build.gradle之外
獻上完整配置:

  • version.properties:
VERSION_CODE=1
VERSION_NAME=1.0
APPLICTION_ID=wenld.moon.color
APP_NAME="xiaojiaDoctor"
XG_V2_ACCESS_ID=sddffa8293d


storefile=Keystore_MH.keystore
keyAlias=MH
KEYSTORE_PASSWORD=password123
KEY_PASSWORD=password789
  • builde.gradle:
apply plugin: 'com.android.application'

def packageTime() {
    return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}

def versionPropsFile = file("version.properties")//引入檔案
Properties versionProps = new Properties()
versionProps.load(new FileInputStream(versionPropsFile))//讀取檔案
android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId versionProps['APPLICTION_ID'].toString()//取出引數
        minSdkVersion 14
        targetSdkVersion 23
        versionCode versionProps['VERSION_CODE'].toInteger()
        versionName versionProps['VERSION_NAME'].toString()
        resValue "string", "app_name", (new String(versionProps['APP_NAME'].toString().getBytes("ISO-8859-1"), "UTF-8"))
        manifestPlaceholders = [
                XG_V2_ACCESS_ID: versionProps['XG_V2_ACCESS_ID'].toString()] //
    }
    signingConfigs { //簽名配置
        release {
            storeFile file(versionProps['storefile'].toString())
            storePassword versionProps['KEYSTORE_PASSWORD'].toString()
            keyAlias versionProps['keyAlias'].toString()
            keyPassword versionProps['KEY_PASSWORD'].toString()
        }
        debug {

        }
    }
    buildTypes {
        release {
            minifyEnabled false//混淆編譯
            shrinkResources true //移除無用的資原始檔
            zipAlignEnabled true      //是否zip對齊
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

            resValue "string", "main_title", "name" //    程式碼內呼叫方式:  R.string maintitle

        }
        debug {
            minifyEnabled false
            shrinkResources true
            zipAlignEnabled true    

            resValue "string", "main_title", "debug_Name"  //除錯版本的標題
        }
    }
    //修改生成的最終檔名
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def outputFile = output.outputFile
            if (outputFile != null && outputFile.name.endsWith('.apk')) {
                File outputDirectory = new File(outputFile.parent);
                def fileName
                if (variant.buildType.name == "release") {
                    // 輸出apk名稱為app_v1.0_2016-03-03.apk
                    fileName = "${defaultConfig.applicationId}_v${defaultConfig.versionName}_${packageTime()}}.apk"
                } else {
                    fileName = "${defaultConfig.applicationId}_v${defaultConfig.versionName}_${packageTime()}_beta.apk"
                }
                output.outputFile = new File(outputDirectory, fileName)
            }
        }
    }
    productFlavors {
        miui {
        }
        wandoujia {

        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar']
}

這樣我們就可以 配置多個 .properties。在budle.gradle中呼叫以下程式碼即可生成不同的apk。

def versionPropsFile = file("version.properties")

推薦:

參考: