Android面試題之Gradle配置篇

本文是Android面試題整理中的一篇,結合右下角目錄食用更佳html

0. Gradle是什麼

  1. Gradle是一個自動化構建工具
  2. 兼容Maven等倉庫
  3. 基於Groovy的特定領域語言來聲明名目設置

1. GradleWraper

  1. Gradle Wrapper是一個腳本文件
  2. 它會在沒有安裝Gradle的狀況下爲咱們下載Gradle,以後咱們就可使用gradlew命令,像使用gradle同樣來使用Gradle了
  3. GradleWraper簡化了gradle的安裝部署

2. Gradle文件結構

  1. settings.gradle:整個Project的配置文件,能夠設置包含哪些module
  2. build.gradle (Project的gradle文件):整個Project的配置文件
  3. build.gradle(Module):Module的配置文件
  4. gradle.properties:能夠在 gradle.properties 文件中配置一些變量

3. Gradle命令

  1. gradlew clean: 清除app目錄下的build文件夾
  2. gradlew check: 執行lint檢查
  3. gradlew assemble:打release和debug包
  4. gradlew build : 執行check和assemble
  5. gradlew assembleRelease/gradlew assembleDebug:打所有渠道的Release或者debug包

4. Gradle常見配置

指定倉庫

repositories {
        jcenter()
    }
複製代碼

指定依賴

dependencies {
        classpath 'com.android.tools.build:gradle:1.3.1'
    }
複製代碼

設置腳本的運行環境

buildscript{}
複製代碼

聲明引用的插件

apply plugin: 'com.android.application'

複製代碼

設置編譯android項目的參數

android {
    // 編譯SDK的版本
    compileSdkVersion 22
    // build tools的版本
    buildToolsVersion "23.0.1"

    //aapt配置
    aaptOptions {
        //不用壓縮的文件
        noCompress 'pak', 'dat', 'bin', 'notice'
        //打包時候要忽略的文件
        ignoreAssetsPattern "!.svn:!.git"
        //分包
        multiDexEnabled true
        //--extra-packages是爲資源文件設置別名:意思是經過該應用包名+R,com.android.test1.R和com.android.test2.R均可以訪問到資源
        additionalParameters '--extra-packages', 'com.android.test1','--extra-packages','com.android.test2'
    }

    //默認配置
    defaultConfig {
        //應用的包名
        applicationId "com.example.heqiang.androiddemo"
        minSdkVersion 21
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }

    //編譯配置
    compileOptions {
        // java版本
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }

    //源文件目錄設置
    sourceSets {
        main {
             //jni lib的位置
             jniLibs.srcDirs = jniLibs.srcDirs << 'src/jniLibs'
             //定義多個資源文件夾,這種狀況下,兩個資源文件夾具備相同優先級,即若是一個資源在兩個文件夾都聲明瞭,合併會報錯。
             res.srcDirs = ['src/main/res', 'src/main/res2']
             //指定多個源文件目錄
             java.srcDirs = ['src/main/java', 'src/main/aidl']
        }
    }

    //簽名配置
    signingConfigs {
        debug {
            keyAlias 'androiddebugkey'
            keyPassword 'android'
            storeFile file('keystore/debug.keystore')
            storePassword 'android'
        }
    }

    buildTypes {
        //release版本配置
        release {
            debuggable false
            // 是否進行混淆
            minifyEnabled true
            //去除沒有用到的資源文件,要求minifyEnabled爲true才生效
            shrinkResources true
            // 混淆文件的位置
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
            signingConfig signingConfigs.debug
            //ndk的一些相關配置,也能夠放到defaultConfig裏面。
            //指定要ndk須要兼容的架構(這樣其餘依賴包裏mips,x86,arm-v8之類的so會被過濾掉)
            ndk {
                abiFilter "armeabi"
            }
        }
        //debug版本配置
        debug {
            debuggable true
            // 是否進行混淆
            minifyEnabled false
            //去除沒有用到的資源文件,要求minifyEnabled爲true才生效
            shrinkResources true
            // 混淆文件的位置
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
            signingConfig signingConfigs.debug
            //ndk的一些相關配置,也能夠放到defaultConfig裏面。
            //指定要ndk須要兼容的架構(這樣其餘依賴包裏mips,x86,arm-v8之類的so會被過濾掉)
            ndk {
                abiFilter "armeabi"
            }
        }
    }
    // lint配置 
    lintOptions {
      //移除lint檢查的error
      abortOnError false
      //禁止掉某些lint檢查
      disable 'NewApi'
    }
}

複製代碼

android中還能夠有如下配置: productFlavors{ } 產品風格配置,ProductFlavor類型;testOptions{ } 測試配置,TestOptions類型; dexOptions{ } dex配置,DexOptions類型;packagingOptions{ } PackagingOptions類型;jacoco{ } JacocoExtension類型。 用於設定 jacoco版本;splits{ } Splits類型。java

5. 幾種依賴的區別

  1. compile:咱們最經常使用的依賴,編譯時提供並打包進apk
  2. provided:編譯時提供但不打包進apk
  3. 在gradlew 3.0 中complie過時了,用implementation和api替代
  4. api = compile
  5. implemention:將該依賴隱藏在內部,而不對外部公開

6. 爲何會有兩套repositories和dependencies

  1. buildscript裏面的那個是插件初始化環境用的,用於設定插件的下載倉庫
  2. android 中是工程依賴的一些模塊和遠程library的下載倉庫的

7. 排除依賴傳遞,解決依賴衝突

  1. exclude: 設置不編譯指定的模塊,排除指定模塊的依賴
  2. transitive:用於自動處理子依賴項,默認爲true,gradle自動添加子依賴項。設置爲false排除全部的傳遞依賴
  3. force:強制設置某個模塊的版本。

8. Gradle打包時的Proguard

  1. 經過在buildTypes中配置minifyEnable來開啓和關閉proguard
  2. 經過proguardFiles 來配置混淆參數與keep的內容
  3. 混淆的做用:
    1. 壓縮(Shrink):檢測並移除代碼中無用的類、字段、方法和特性(Attribute)。
    2. 優化(Optimize):對字節碼進行優化,移除無用的指令。
    3. 混淆(Obfuscate):使用a,b,c,d這樣簡短而無心義的名稱,對類、字段和方法進行重命名。
    4. 預檢(Preveirfy):在Java平臺上對處理後的代碼進行預檢,確保加載的class文件是可執行的。

9. 依賴中的動態版本聲明

dependencies {
    //依賴最新的1.x版本
    compile "org.codehaus.cargo:cargo-ant:1.+"
}
複製代碼

10. 多渠道打包1

  1. 在AndroidManifest.xml配置mete-data
<meta-data
    android:name="UMENG_CHANNEL"
    android:value="Channel_ID" />
複製代碼
  1. 配置Flavors:
android {  
    productFlavors {
        xiaomi {
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "xiaomi"]
        }
        _360 {
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "_360"]
        }
        baidu {
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "baidu"]
        }
        wandoujia {
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "wandoujia"]
        }
    }  
}

    
或者批量修改

android {  
    productFlavors {
        xiaomi {}
        _360 {}
        baidu {}
        wandoujia {}
    }  

    productFlavors.all { 
        flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name] 
    }
}

複製代碼
  1. 在APP內讀取 mete-data 配置肯定渠道
  2. 而後用 ./gradlew assembleRelease 這條命令會把Product Flavor下的全部渠道的Release版本都打出來。

11. 多渠道打包2

  1. 由於以上方法須要屢次編譯,速度較慢,當渠道變多以後不適合多渠道打包
  2. 改進的方法1 : apk反編譯後重寫AndroidManifest文件,再從新編譯簽名
  3. 改進的方法2 : 若是在META-INF目錄內添加空文件,能夠不用從新簽名應用。所以,經過爲不一樣渠道的應用添加不一樣的空文件,能夠惟一標識一個渠道

12. 多渠道打包3

  1. 在採用V2簽名後,以上方法再也不適用
  2. 考慮到V2簽名的特色(對APK Signing Block是不進行驗證的),咱們向V2簽名後的APK簽名區塊寫入渠道號,實現多渠道打包

15. 其餘用途

由於v1簽名能夠在不改變簽名狀況下二次打包,咱們能夠在gradle中對dex文件進行本身的簽名android

16. 哪些不作混淆

  1. Android系統組件
  2. JNI
  3. 反射
  4. WebView的JS調用
  5. 內部類
  6. Annottation
  7. enum
  8. 範型
  9. 序列化
  10. 第三方

17. Gradle 生命週期

  1. 初始化階段:會去讀取根工程中setting.gradle中的include信息,決定有哪幾個工程加入構建, 建立project實例,好比下面有三個工程: include ':app', ':lib1', ':lib2
  2. 配置階段:,會去執行全部工程的build.gradle腳本,配置project對象,一個對象由多個任務組成, 此階段也會去建立、配置task及相關信息。
  3. 運行階段:根據gradle命令傳遞過來的task名稱,執行相關依賴任務

18. 如何經過Gradle配置差別較大(20%差別)的多渠道包

經過配置productFlavors,將區別代碼放置在對應的問價下,gradle會自動打出相應包git

相關文章
相關標籤/搜索