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

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