主頁 > 移動端開發 > Android使用gradle入門

Android使用gradle入門

2021-11-15 11:22:49 移動端開發

1.gradle是什么?

Gradle是新一代的自動化構建工具一個基于JVM的構建工具,它是一個獨立的專案,跟AS,Android無關,類似Ant,Maven這類構建工具都是基于xml來進行描述的,很臃腫,而Gradle采用的是一種叫做Groovy的語言,語法跟Java語法很像,但是一種動態語言,而且在Java基礎上做了不少改進,用起來更加簡潔、靈活,而且Gradle完全兼容Maven、lvy,這點基本上宣布Maven、lvy可以被拋棄了,Gradle的推出主要以Java應用為主,當然目前還支持Android、C、C++

構建工具就是對你的專案進行編譯、運行、簽名、打包、依賴管理等一系列功能集合,傳統的構建工具有Make、Ant、Maven、lvy等,而Gradle是新一代的自動化構建工具;

gradle優勢(gradle提供了什么)

1). 一種可切換的,像maven一樣的基于約定的構建框架,卻又從不鎖住你(約定優于配置)

2). 強大的支持多工程的構建

3). 強大的依賴管理(基于Apache Ivy),提供最大的便利去構建你的工程

4). 全力支持已有的Maven或者Ivy倉庫基礎建設

5). 支持傳遞性依賴管理,在不需要遠程倉庫和pom.xml和ivy組態檔的前提下

6). 基于groovy腳本構建,其build腳本使用groovy語言撰寫

7). 具有廣泛的領域模型支持你的構建

參考:gradle_百度百科

2.gradle如何參考?

Gradle 跟 Android Studio 其實沒有關系,但是 Gradle 官方還是很看重 Android 開發的,Google 在推出 AS 的時候選中了 Gradle 作為構建工具,為了支持 Gradle 能在 AS 上使用,Google 做了個 AS 的插件叫 Android Gradle Plugin所以我們能在 AS 上使用 Gradle 完全是因為這個插件的原因,在專案的根目錄有個 build.gradle 檔案,里面有這么一句代碼:

buildscript {
    dependencies {
        classpath "com.android.tools.build:gradle:4.1.2"
    }
}

這個就是依賴 gradle 插件的代碼,后面的版本號代表的是 android gradle plugin 的版本,而不是 Gradle 的版本,這個是 Google 定的,跟 Gradle 官方沒關系,

Android Gradle Plugin每個版本的具體變化和具體功能參考:Android Gradle 插件版本說明 | Android 開發者 | Android Developers

3.gradle、android gradle plugin、gradle wrapper區別和聯系

  • Gradle是個構建系統,可以簡化你的編譯、打包、測驗程序,熟悉Java的同窗,能夠把Gradle類比成Maven,
  • Gradle Wrapper的做用是簡化Gradle自己的安裝、部署,現在默認新建一個專案,然后點擊 AS 上的運行,默認就會直接幫你安裝 Gradle ,我們不需要額外的安裝 Gradle 了,但是其實這個 Gradle 不是真正的 Gradle ,他叫 Gradle Wrapper ,意為 Gradle 的包裝,什么意思呢?假設我們本地有多個專案,一個是比較老的專案,還用著 Gradle 1.0 的版本,一個是比較新的專案用了 Gradle 2.0 的版本,但是你兩個專案肯定都想要同時運行的,如果你只裝了 Gradle 1.0 的話那肯定不行,所以為了解決這個問題,Google 推出了 Gradle Wrapper 的概念,就是他在你每個專案都配置了一個指定版本的 Gradle ,你可以理解為每個 Android 專案本地都有一個小型的 Gradle ,通過這個每個專案你可以支持用不同的 Gradle 版本來構建專案,
  • Android Plugin for Gradle是一堆適合Android開發的Gradle插件的集合,主要由Google的Android團隊開發,Gradle不是Android的專屬構建系統,可是有了Android Plugin for Gradle的話,你會發現使用Gradle構建Android專案尤為的簡單,

4.Android工程gradle配置?

4.1.Android下多模塊gradle配置目錄結構

project

├─── setting.gradle

├─── build.grade

├─── app

│ └─── build.gradle

└─── libraries

├─── library1

│ └─── build.gradle

└─── library2

└─── build.gradle

以一個測驗專案為例,來介紹下一個完整的Android專案包含的基本Gradle相關的配置:

紅色標記部分從上到下一步步分析;

4.1.1.FlotWindow/app/build.gradle

這個檔案是app檔案夾下這個Module的gradle組態檔,也可以算是整個專案最主要的gradle組態檔,具體里面的配置下面會介紹;

每個Module都需要有一個gradle組態檔,語法都是一樣,唯一不同的是開頭可能不一樣;

可以獨立為APP的Module使用開頭:

plugins {
    id 'com.android.application'
}

作為library的Module使用開頭:

plugins {
    id 'com.android.library'
}

4.1.2FloatWindow/gradle

這個目錄下有個wrapper檔案夾,里面可以看到兩個檔案,我們主要看下gradle-wrapper.properties這個檔案的內容:

#Thu Nov 04 13:56:00 CST 2021
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip

其中GRADLE_USER_HOME通常指~/.gradle,從圖示專案中能夠知道我要使用gradle-6.5版本,從https://services.gradle.org/distributions/gradle-6.5-bin.zip下載,下載到本地的~/.gradle/wrapper/dists目錄,那是否是各個專案的Gradle都要經過Gradle Wrapper下載,能不能全部的專案共用一個Gradle?這樣理論上是能夠的,可是因為Gradle自己不必定保持徹底的兼容性因此新老專案共用一個Gradle有時可能會遇到意想不到的問題,指定對應版本的Gradle,而不經過Gradle Wrapper下載的設定方式是選擇Specified location同時指定Gradle home

4.1.3FloatWindow/build.gradle

這個檔案是整個專案的gradle基礎組態檔,默認的內容就是宣告了android gradle plugin的版本;

buildscript {
    dependencies {
        classpath "com.android.tools.build:gradle:4.1.2"
    }
}

4.1.4FloatWindow/setting.gradle

這個檔案是全域專案組態檔,里面主要生命一些需要加入gradle的module,我們看看FloatWindow內容:

include ':app'
include ':library'
rootProject.name = "FloatWindowL"

5.Android工程下全域build.gradle配置和Module下build.gradle配置說明?

5.1Project全域build.gradle配置

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {//這里是gradle腳本執行所需依賴,分別對應的maven庫和插件
    repositories {
        google()//Android Studio3.0后新增了google()配置,可以參考google上的開源專案
        jcenter()//是一個類似于github的代碼托管倉庫,宣告了jcenter()配置,可以輕松參考 jcenter上的開源專案
    }
    dependencies {
        //此處是android的插件gradle,gradle是一個強大的專案構建工具
        classpath "com.android.tools.build:gradle:4.1.2"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {    //這里是專案本身需要的依賴,比如專案所需的maven庫
    repositories {
        google()
        jcenter()
    }
}
//運行gradle clean時,執行此處定義的task任務;
//該任務繼承自Delete,洗掉根目錄中的build目錄
//相當于執行Delete.delete(rootProject.bulidDir)
//gradle使用groovy語言,呼叫method時可以不用加(),
task clean(type: Delete) {
    delete rootProject.buildDir
}
  • buildscript{}閉包里是gradle腳本執行所需依賴,分別是對應的maven庫和插件;
  • allprojects{}閉包里是專案本身需要的依賴,比如專案所需要的maven庫;
  • task clean(type: Delete){}是運行gradle clean時,執行此處定義的task任務,該任務繼承自Delete,洗掉根目錄中的build目錄;其中buildscript包含repositories閉包和dependencies閉包;

repositories{}閉包:配置遠程倉庫

該閉包中宣告了jcenter()和google()的配置,其中jcenter是一個代碼托管倉庫,上面托管了很多Android開源專案,在這里配置了jcenter后我們可以在專案中方便參考jcenter上的開源專案,從Android Studio3.0后新增了google()配置,可以參考google上的開源專案;

dependencies{}閉包:配置構造工具

該閉包使用classpath宣告了一個gradle插件,由于gradle并不是用來構建Android專案,因此此處引入相關插件來構建Android專案,啟動4.1.2為該插件的版本號,可以根據最新的版本號調整;

5.2Module下build.gradle配置

從檔案內容可以看出,主要分為三部分,如下:

plugins {
    id 'com.android.application'
}

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.3"

    defaultConfig {
        applicationId "com.gome.floatwindowl"
        minSdkVersion 17
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {

    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'com.google.android.material:material:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'androidx.navigation:navigation-fragment:2.2.2'
    implementation 'androidx.navigation:navigation-ui:2.2.2'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}

5.2.1plugin

//宣告Android程式
//com.android.application 表示這是一個應用程式模塊
//com.android.library 標識這是一個庫模塊
//區別:前者可以直接運行,后者是依附別的應用程式運行
plugins {
    id 'com.android.application'
}

檔案中第一行使用plugin表示應用一個插件,該插件一般有兩種值選擇:

  • com.android.application,表示該模塊為應用程式模塊,可以直接運行,打包得到的是.apk檔案
  • com.android.library,表示該模塊為庫模塊,只能作為代碼庫依附于別的應用程式模塊來運行,打包得到的是.aar檔案

5.2.2android{}閉包

這個閉包主要為了配置專案構建的各種屬性;

添加signingConfigs{}閉包:

signingConfigs {// 自動化打包配置
    release {// 線上環境
        keyAlias 'test'
        keyPassword '123456'
        storeFile file('test.keystore')
        storePassword '123456'
    }
    debug {// 開發環境
        keyAlias 'test'
        keyPassword '123456'
        storeFile file('test.keystore')
        storePassword '123456'
    }
}

可以手動添加簽名配置,也可以通過Project Structure選中app,點擊Signing添加,具體步驟如下圖所示:

簽名配置完成后可以方便帶簽名打包,在module的Build Variants中有兩個Type,分別是debug和release,可以選擇任意一個型別進行打包,并且他們會利用各自配置的Key進行打包,執行 Run app或者Build->Build apk就會自動在module name/app/build/outputs/apk路徑下生成Apk檔案,另一種打包方式是Build->Generate Signed APK填寫簽名資訊生成Apk,

compileSdkVersion:設定編譯時用的Android版本;

buildToolsVersion:設定編譯時使用的構建工具版本,Android Studio3.0后去除此項配置;

defaultConfig{}閉包:

compileSdkVersion 30        //設定專案編譯時用的Android版本
buildToolsVersion "30.0.3"
defaultConfig {
    applicationId "com.gome.floatwindowl"        //專案包名
    minSdkVersion 17        //專案最低的兼容版本
    targetSdkVersion 30        //專案的目標版本
    versionCode 1          //版本號
    versionName "1.0"        //版本名稱
        
    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" //表明要使用AndroidJUnitRunner進行單元測驗
}
  • applicationId:指定了專案的包名,
  • minSdkVersion:指定專案最低兼容的版本,如果設備小于這個版本或者大于maxSdkVersion(一般不用)將無法安裝這個應用,這里指定為16,表示最低兼容到Android 4.1系統,
  • targetSdkVersion:指定專案的目標版本,表示在該目標版本上已經做過充分測驗,系統會為該應用啟動一些對應該目標系統的最新功能特性,Android系統平臺的行為變更,只有targetSdkVersion的屬性值被設定為大于或等于該系統平臺的API版本時,才會生效,例如,若指定targetSdkVersion值為22,則表示該程式最高只在Android5.1版本上做過充分測驗,在Android6.0系統上(對應targetSdkVersion為23)擁有的新特性如系統運行時權限等功能就不會被啟用,
  • versionCode:表示版本號,一般每次打包上線時該值只能增加,打包后看不見,
  • versionName:表示版本名稱,展示在應用市場上,
  • testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"表明要使用AndroidJUnitRunner進行單元測驗,

buildTypes{}閉包:

這個閉包主要指定生成安裝檔案的主要配置,一般包含兩個子閉包,一個是debug閉包,用于指定生成測驗版安裝檔案的配置,可以忽略不寫;另一個是release閉包,用于指定生成正式版安裝檔案的配置,兩者能配置的引數相同,最大的區別默認屬性配置不一樣,兩種模式支持的屬性配置如下圖:

 buildTypes {// 生產/測驗環境配置
        release {// 生產環境
            buildConfigField("boolean", "LOG_DEBUG", "false")//配置Log日志
            buildConfigField("String", "URL_PERFIX", "\"https://release.cn/\"")// 配置URL前綴
            minifyEnabled false//是否對代碼進行混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的規則檔案
            signingConfig signingConfigs.release//設定簽名資訊
            pseudoLocalesEnabled false//是否在APK中生成偽語言環境,幫助國際化的東西,一般使用的不多
            zipAlignEnabled true//是否對APK包執行ZIP對齊優化,減小zip體積,增加運行效率
            applicationIdSuffix 'test'//在applicationId 中添加了一個后綴,一般使用的不多
            versionNameSuffix 'test'//在applicationId 中添加了一個后綴,一般使用的不多
        }
        debug {// 測驗環境
            buildConfigField("boolean", "LOG_DEBUG", "true")//配置Log日志
            buildConfigField("String", "URL_PERFIX", "\"https://test.com/\"")// 配置URL前綴
            minifyEnabled false//是否對代碼進行混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的規則檔案
            signingConfig signingConfigs.debug//設定簽名資訊
            debuggable false//是否支持斷點除錯
            jniDebuggable false//是否可以除錯NDK代碼
            renderscriptDebuggable false//是否開啟渲染腳本就是一些c寫的渲染方法
            zipAlignEnabled true//是否對APK包執行ZIP對齊優化,減小zip體積,增加運行效率
            pseudoLocalesEnabled false//是否在APK中生成偽語言環境,幫助國際化的東西,一般使用的不多
            applicationIdSuffix 'test'//在applicationId 中添加了一個后綴,一般使用的不多
            versionNameSuffix 'test'//在applicationId 中添加了一個后綴,一般使用的不多
        }
    }

release{}閉包和debug{}閉包兩者能配置的引數相同,最大的區別默認屬性配置不一樣:

  • minifyEnabled:表明是否對代碼進行混淆,true表示對代碼進行混淆,false表示對代碼不進行混淆,默認的是false,
  • proguardFiles:指定混淆的規則檔案,這里指定了proguard-android.txt檔案和proguard-rules.pro檔案兩個檔案,proguard-android.txt檔案為默認的混淆檔案,里面定義了一些通用的混淆規則,proguard-rules.pro檔案位于當前專案的根目錄下,可以在該檔案中定義一些專案特有的混淆規則,
  • buildConfigField:用于解決Beta版本服務和Release版本服務地址不同或者一些Log列印需求控制的,例如:配置buildConfigField(“boolean”, “LOG_DEBUG”, “true”),這個方法接收三個非空的引數,第一個:確定值的型別,第二個:指定key的名字,第三個:傳值,呼叫的時候BuildConfig.LOG_DEBUG即可呼叫,
  • debuggable:表示是否支持斷點除錯,release默認為false,debug默認為true,
  • jniDebuggable:表示是否可以除錯NDK代碼,使用lldb進行c和c++代碼除錯,release默認為false
  • signingConfig:設定簽名資訊,通過signingConfigs.release或者signingConfigs.debug,配置相應的簽名,但是添加此配置前必須先添加signingConfigs閉包,添加相應的簽名資訊,
  • renderscriptDebuggable:表示是否開啟渲染腳本就是一些c寫的渲染方法,默認為false,
  • renderscriptOptimLevel:表示渲染等級,默認是3,
  • pseudoLocalesEnabled:是否在APK中生成偽語言環境,幫助國際化的東西,一般使用的不多,
  • applicationIdSuffix:和defaultConfig中配置是一的,這里是在applicationId 中添加了一個后綴,一般使用的不多,
  • versionNameSuffix:表示添加版本名稱的后綴,一般使用的不多,
  • zipAlignEnabled:表示是否對APK包執行ZIP對齊優化,減小zip體積,增加運行效率,release和debug默認都為true,

sourceSets{}閉包:配置目錄指向

sourceSets {//目錄指向配置
        main {
            jniLibs.srcDirs = ['libs']//指定lib庫目錄
        }
    }

配置 jniLibs.srcDirs = [‘libs’],可以在Android studio的Android視圖下生成jniLibs檔案夾,可以方便我們存放jar包和庫檔案,其中Android視圖下的jniLibs和project視圖下的libs指向同一檔案夾(app→libs),如下圖所示:

當需要除錯版本和正式版本使用不同的manifest檔案時,可以做如下配置:

sourceSets {
main {
if (isDebug.toBoolean()) {
manifest.srcFile 'src/main/debug/AndroidManifest.xml'
} else {
manifest.srcFile 'src/main/release/AndroidManifest.xml'
}
}
}

packagingOptions{}閉包:打包時的相關配置

當專案中依賴的第三方庫越來越多時,有可能會出現兩個依賴庫中存在同一個(名稱)檔案,如果這樣,Gradle在打包時就會提示錯誤(警告),那么就可以根據提示,然后使用以下方法將重復的檔案剔除,比較常用的是通過exclude去除重復的檔案,例如:

 packagingOptions{
        //pickFirsts做用是 當有重復檔案時 打包會報錯 這樣配置會使用第一個匹配的檔案打包進入apk
        // 表示當apk中有重復的META-INF目錄下有重復的LICENSE檔案時  只用第一個 這樣打包就不會報錯
        pickFirsts = ['META-INF/LICENSE']

        //merges何必 當出現重復檔案時 合并重復的檔案 然后打包入apk
        //這個是有默認值得 merges = [] 這樣會把默默認值去掉  所以我們用下面這種方式 在默認值后添加
        merge 'META-INF/LICENSE'

        //這個是在同時使用butterknife、dagger2做的一個處理,同理,遇到類似的問題,只要根據gradle的提示,做類似處理即可,
        exclude 'META-INF/services/javax.annotation.processing.Processor'
    }

productFlavors{}閉包:多個渠道配置

這個配置是經常會使用到的,通常在適配多個渠道的時候,需要為特定的渠道做部分特殊的處理,比如設定不同的包名、應用名等,場景:當我們使用友盟統計時,通常需要設定一個渠道ID,那么我們就可以利用productFlavors來生成對應渠道資訊的包,如:

productFlavors {
    wandoujia {
        //豌豆莢渠道包配置
        manifestPlaceholders = [UMENG_CHANNEL_VALUE: "wandoujia"]
        //manifestPlaceholders的使用在后續章節(AndroidManifest里的占位符)中介紹
    }
    xiaomi {
        manifestPlaceholders = [UMENG_CHANNEL_VALUE: "xiaomi"]
        applicationId "com.wiky.gradle.xiaomi" //配置包名

    }
    _360 {
        manifestPlaceholders = [UMENG_CHANNEL_VALUE: "_360"]
    }
    //...
}

當然也有更簡潔的方式

android {  
    productFlavors {
        wandoujia {}
        xiaomi {}
        _360 {}
       //...
    }  

    productFlavors.all { 
        //批量修改,類似一個循序遍歷
        flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name] 
    }
}

配置完之后,在命令列視窗中(Terminal)中輸入gradlew assembleRelease(windows)即可開始打包,在Mac系統中對應指令應該是./gradlew assembleRelease,當然,如果想要debug版本的包,將指令中assembleRelease改為assembleDebug即可,最后生成的包還是在
app/build/outputs/apk中,默認命名格式如app-wandoujia-release-unsigned.apk,在module的Build Variants中可以選擇相應的渠道,
注:Android Studio3.0需在主app的build.gradle里面的
defaultConfig {applicationId:"xxx.xxx.xxx"
targetSdkVersion:***
minSdkVersion :***
versionCode:***
versionName :***
//版本名后面添加一句話,意思就是flavor dimension 它的維度就是該版本號,這樣維度就是都是統一的了
flavorDimensions “versionCode”
}

lintOptions{}閉包:代碼掃描分析

Lint 是Android Studio 提供的 代碼掃描分析工具,它可以幫助我們發現代碼結構/質量問題,同時提供一些解決方案,而且這個程序不需要我們手寫測驗用例,

Lint 發現的每個問題都有描述資訊和等級(和測驗發現 bug 很相似),我們可以很方便地定位問題,同時按照嚴重程度進行解決,

//程式在編譯的時候會檢查lint,有任何錯誤提示會停止build,我們可以關閉這個開關
    lintOptions {
        abortOnError false //即使報錯也不會停止打包
        checkReleaseBuilds false  //打包release版本的時候進行檢測
    }

5.2.3dependencies{}閉包

該閉包定義了專案的依賴關系,一般專案都有三種依賴方式:本地依賴、庫依賴和遠程依賴,本地依賴可以對本地的jar包或目錄添加依賴關系,庫依賴可以對專案中的庫模塊添加依賴關系,遠程依賴可以對jcener庫上的開源專案添加依賴關系,從Android Studio3.0后compile引入庫不在使用,而是通過api和implementation,api完全等同于以前的compile,用api引入的庫整個專案都可以使用,用implementation引入的庫只有對應的Module能使用,其他Module不能使用,由于之前的專案統一用compile依賴,導致的情況就是模塊耦合性太高,不利于專案拆解,使用implementation之后雖然使用起來復雜了但是做到降低偶合興提高安全性,

dependencies {//專案的依賴關系
    implementation fileTree(include: ['*.jar'], dir: 'libs')//本地jar包依賴
    implementation 'com.android.support:appcompat-v7:27.1.1'//遠程依賴
    implementation 'com.android.support.constraint:constraint-layout:1.1.2'
    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'
}
  • implementation fileTree(include: [’*.jar’], dir: ‘libs’):implementation fileTree是一個本地依賴宣告,表示將libs目錄下所有.jar后綴的檔案都添加到專案的構建路徑當中,
  • implementation ‘com.android.support:appcompat-v7:27.1.1’:implementation陳述句為 遠程依賴宣告,'com.android.support:appcompat-v7:27.1.1’為一個標準的遠程依賴庫格式,其中com.android.support為域名部分,用于區分不同公司的庫;appcompat-v7為組件名稱,用于區分同一個公司的不同庫;27.1.1為版本號,用于區分同一個庫的不同版本,加上這句宣告后,Gradle在構建專案時會先檢查一下本地是否已經快取過該庫,若沒有快取則自動聯網下載,下載后自動添加到專案的構建路徑中去,
  • testImplementation和androidTestImplementation:表示宣告測驗用例庫,

5.3Module完整的build.gradle配置

// 宣告是Android程式,
//com.android.application 表示這是一個應用程式模塊
//com.android.library 標識這是一個庫模塊
//而這區別:前者可以直接運行,后著是依附別的應用程式運行
apply plugin: 'com.android.application'

android {
    signingConfigs {// 自動化打包配置
        release {// 線上環境
            keyAlias 'test'
            keyPassword '123456'
            storeFile file('test.jks')
            storePassword '123456'
        }
        debug {// 開發環境
            keyAlias 'test'
            keyPassword '123456'
            storeFile file('test.jks')
            storePassword '123456'
        }
    }
    compileSdkVersion 27//設定編譯時用的Android版本
    defaultConfig {
        applicationId "com.billy.myapplication"//專案的包名
        minSdkVersion 16//專案最低兼容的版本
        targetSdkVersion 27//專案的目標版本
        versionCode 1//版本號
        versionName "1.0"//版本名稱
        flavorDimensions "versionCode"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"//表明要使用AndroidJUnitRunner進行單元測驗
    }
    buildTypes {// 生產/測驗環境配置
        release {// 生產環境
            buildConfigField("boolean", "LOG_DEBUG", "false")//配置Log日志
            buildConfigField("String", "URL_PERFIX", "\"https://release.cn/\"")// 配置URL前綴
            minifyEnabled false//是否對代碼進行混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的規則檔案
            signingConfig signingConfigs.release//設定簽名資訊
            pseudoLocalesEnabled false//是否在APK中生成偽語言環境,幫助國際化的東西,一般使用的不多
            zipAlignEnabled true//是否對APK包執行ZIP對齊優化,減小zip體積,增加運行效率
            applicationIdSuffix 'test'//在applicationId 中添加了一個后綴,一般使用的不多
            versionNameSuffix 'test'//在applicationId 中添加了一個后綴,一般使用的不多
        }
        debug {// 測驗環境
            buildConfigField("boolean", "LOG_DEBUG", "true")//配置Log日志
            buildConfigField("String", "URL_PERFIX", "\"https://test.com/\"")// 配置URL前綴
            minifyEnabled false//是否對代碼進行混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的規則檔案
            signingConfig signingConfigs.debug//設定簽名資訊
            debuggable false//是否支持斷點除錯
            jniDebuggable false//是否可以除錯NDK代碼
            renderscriptDebuggable false//是否開啟渲染腳本就是一些c寫的渲染方法
            zipAlignEnabled true//是否對APK包執行ZIP對齊優化,減小zip體積,增加運行效率
            pseudoLocalesEnabled false//是否在APK中生成偽語言環境,幫助國際化的東西,一般使用的不多
            applicationIdSuffix 'test'//在applicationId 中添加了一個后綴,一般使用的不多
            versionNameSuffix 'test'//在applicationId 中添加了一個后綴,一般使用的不多
        }
    }

    sourceSets {//目錄指向配置
        main {
            jniLibs.srcDirs = ['libs']//指定lib庫目錄
        }
    }

    packagingOptions{//打包時的相關配置
        //pickFirsts做用是 當有重復檔案時 打包會報錯 這樣配置會使用第一個匹配的檔案打包進入apk
        // 表示當apk中有重復的META-INF目錄下有重復的LICENSE檔案時  只用第一個 這樣打包就不會報錯
        pickFirsts = ['META-INF/LICENSE']

        //merges何必 當出現重復檔案時 合并重復的檔案 然后打包入apk
        //這個是有默認值得 merges = [] 這樣會把默默認值去掉  所以我們用下面這種方式 在默認值后添加
        merge 'META-INF/LICENSE'

        //這個是在同時使用butterknife、dagger2做的一個處理,同理,遇到類似的問題,只要根據gradle的提示,做類似處理即可,
        exclude 'META-INF/services/javax.annotation.processing.Processor'
    }

    productFlavors {
        wandoujia {}
        xiaomi {}
        _360 {}
    }

    productFlavors.all {
            //批量修改,類似一個循序遍歷
        flavor -> flavor.manifestPlaceholders = [IFLYTEK_CHANNEL: name]
    }

    //程式在編譯的時候會檢查lint,有任何錯誤提示會停止build,我們可以關閉這個開關
    lintOptions {
        abortOnError false
        //即使報錯也不會停止打包
        checkReleaseBuilds false
        //打包release版本的時候進行檢測
    }

}

dependencies {
    //專案的依賴關系
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    //本地jar包依賴
    implementation 'com.android.support:appcompat-v7:27.1.1'
    //遠程依賴
    implementation 'com.android.support.constraint:constraint-layout:1.1.2'
    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'
}

6.Android的APK編譯流程

APK的構建程序可以根據官方提供的流程圖如下圖所示

這個APK構建的程序主要分為以下幾步:
1. 通過AAPT(Android Asset Packaging Tool)打包res資源檔案,比如AndroidManifest.xml、xml布局檔案等,并將這些xml檔案編譯為二進制,其中assets和raw檔案夾的檔案不會被編譯為二進制,最侄訓生成R.java和resources.arsc檔案,
2. AIDL工具會將所有的aidl介面轉化為對應的Java介面,
3. 所有的Java代碼,包括R.java和Java介面都會被Java編譯器編譯成.class檔案,
4. Dex工具會將上一步生成的.class檔案、第三庫和其他.class檔案編譯成.dex檔案,
5. 上一步編譯生成的.dex檔案、編譯過的資源、無需編譯的資源(如圖片等)會被ApkBuilder工具打包成APK檔案,
6. 使用Debug Keystore或者Release Keystore對上一步生成的APK檔案進行簽名,
7. 如果是對APK正式簽名,還需要使用zipalign工具對APK進行對齊操作,這樣應用運行時會減少記憶體的開銷,

從以上步驟可以看出,APK的構建程序是比較繁瑣的,而且這個構建程序又是時常重復的,如果沒有構建工具,手動去完成構建作業,無疑對于開發人員是個折磨,也會產生諸多的問題,導致專案開發周期變長,

7.認識下幾個命令

上面提到了,假設我們沒有 IDE ,只有類似 Sublime、Atom、Vim這種輕量編輯器怎么辦?那我們就沒法開發 Android 了么?然而只要有構建工具,不需要 IDE 我們一樣有辦法開發,這個時候我們就需要用到幾個有用的 Gradle 命令了:

./gradlew -v 版本號

./gradlew clean 清除9GAG/app目錄下的build檔案夾

./gradlew build 檢查依賴并編譯打包

這里注意的是 ./gradlew build 命令把 debug、release 環境的包都打出來,如果正式發布只需要打 Release 的包,該怎么辦呢,下面介紹一個很有用的命令 assemble , 如

./gradlew assembleDebug 編譯并打Debug包

./gradlew assembleRelease 編譯并打Release的包

值得注意的是,以上所有命令都是在終端里執行,并且必須要切換到所在專案的根目錄下執行,win系統直接執行 gradlew ,

參考:

史上最全Android build.gradle配置詳解_林偉茂的博客-CSDN博客

Android SourceSet 使用 參考 示例_TDC的專欄-CSDN博客

給 Android 初學者的 Gradle 知識普及 - 知乎

Android Gradle是什么?_xuwei_net的專欄-CSDN博客_android gradle

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/357149.html

標籤:其他

上一篇:iOS——FMDB的簡單使用

下一篇:用iPad撰寫C/C++代碼(計算機考研黨也能用iPad寫演算法題)

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more