Android編譯流程和Gradle使用

流程

Android工程的編譯打包是個複雜的過程,期間既涉及到工程自身的源代碼、資源文件、AIDL文件,又涉及到工程所依賴的庫文件(Library, JAR, AAR)等,需要由多個工具分多個步驟完成。本文將對編譯打包的流程進行描述,並對控制這個流程用到的gradle文件體系進行介紹。

打包過程

下圖是谷歌官網給出的一個典型的apk構建的過程,比較概括。主要包括兩個過程,首先是編譯過程,編譯的內容包括本工程的文件以及依賴的各種庫文件,編譯的輸出包括dex文件和編譯後的資源文件。然後是打包過程。配合Keystore對第一步的輸出進行簽名對齊,生成最終的apk文件。

典型的APK構建過程

下面這張圖對上面的步驟以及每步用到的工具進行了細分,概括如下:

1. Java編譯器對工程本身的java代碼進行編譯,這些java代碼有三個來源:app的源代碼,由資源文件生成的R文件(aapt工具),以及有aidl文件生成的java接口文件(aidl工具)。產出爲.class文件。
2. .class文件和依賴的三方庫文件通過dex工具生成Delvik虛擬機可執行的.dex文件,可能有一個或多個,包含了所有的class信息,包括項目自身的class和依賴的class。產出爲.dex文件。
3. apkbuilder工具將.dex文件和編譯後的資源文件生成未經簽名對齊的apk文件。這裏編譯後的資源文件包括兩部分,一是由aapt編譯產生的編譯後的資源文件,二是依賴的三方庫裏的資源文件。產出爲未經簽名的.apk文件。
4. 分別由Jarsigner和zipalign對apk文件進行簽名和對齊,生成最終的apk文件。

總結爲:編譯–>DEX–>打包–>簽名和對齊

Android Apk編譯流程

Gradle文件體系

Android工程通過gradle文件管理各項配置,gradle文件利用DSL(Domain Specific Language)語言描述配置,並使用Groovy語言處理編譯邏輯。一個典型的Android工程結構如下:

典型的Android Project結構

在這裏gradle文件分佈在幾個不同的層級,Project層級以及Module層級。

1. Project層級的settings.gradle描述的是該Project包含哪些Module
include ':presentation', ':qamodel', ':chatcommonmodule', ':qa', ':unlimit'
2. Project層級的build.gradle描述的是作用於所有Module的配置,包括gradle版本等。
3. Module層級的build.gradle。每個Module下都有一個作用於該Module的build.gradle文件,描述了該Module相關的配置。這些配置主要包括:BuildTypes,ProductFlavors,Dependency,SigningSettings等。

下面將簡要介紹Module層級的build.gradle配置文件。

Configure Build Types

Module層級的gradle文件,buildTypes段。Android會自動在buildTypes段創建release和debug兩類配置,debug是默認存在的,並且設置了debuggable true,默認情況下不會展示出來,除非你要修改debug的配置。如下:

android {
    buildTypes {        
        release {            
            minifyEnabled false            
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        
        }    
    }
}

Configure Product Flavors

Module層級的gradle文件,productFlavors段。productFlavors的設置會自動使用defaultConfig配置。如果設置了幾個不同的productFlavors,它們會共用defaultConfig配置,以及自己各自的配置,如applicationId。注意,不同的productFlavors都是通過manifest文件裏的package屬性定義的名字來引用R文件,而不是使用各自的applicationId,所以applicationId其實是可以隨意取名的。

android {    
    ...    
    defaultConfig {
        applicationId "com.magic.wdl.simpledaggerdemo"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }    
    buildTypes {...}    
    productFlavors {        
        demo {            
            applicationId "com.magic.wdl.simpledaggerdemo.demo"            
            versionName "1.0-demo"        
        }        

        full {            
            applicationId "com.magic.wdl.simpledaggerdemo.full"            
            versionName "1.0-full"        
        }    
    }
}

不同的build type和product Flavors可以互相組合,生成m*n種apk文件(不同的Build Variant[版本]),比如:
demoDebug
demoRelease
fullDebug
fullRelease

通過 Build > Select Build Variant可以選擇要生成的apk類型。

select build variant

Configure dependency

dependencies段配置依賴的Module或是本地以及遠端的binary。

dependencies {    
    // Module依賴
    compile project(":mylibrary")    
    // 遠端Binary依賴    
    compile 'com.android.support:appcompat-v7:23.4.0'    
    // 本地Binary依賴,指定路徑app/libs/
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

Configure signing settings

signingConfigs段配置簽名信息,生成簽名的方法參照這裏

signingConfigs {        
    release {            
        storeFile file("myreleasekey.keystore")            
        storePassword "password"            
        keyAlias "MyReleaseKey"            
        keyPassword "password"        
    }    
}    

buildTypes {        
    release {            
        ...            
        signingConfig signingConfigs.release        
    }
}

參考:
https://developer.android.com/studio/build/index.html
http://www.alittlemadness.com/2010/06/07/understanding-the-android-build-process/
http://www.jianshu.com/p/02dfa291d078
http://czak.pl/2016/05/31/handbuilt-android-project.html

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