Gradle編譯打包小結

本文鏈接:https://blog.csdn.net/byhook/article/details/51746825

 

以前用Eclipse打包,比較笨,右鍵導出簽名 
現在一直是用的Android Studio來開發 
用Gradle編譯打包非常方便 
筆者整理的平時編譯打包的配置,記錄一下,避免遺忘 

大概分爲以下幾個步驟
1、使用aapt工具將res資源文件生成R.java文件
2、使用aidl工具將aidl文件生成對應java文件
3、使用javac命令編譯工程源代碼和上面兩步生成的文件,生成class文件
4、通過dex工具將class文件和第三方jar包打成dex文件
5、用aapt工具將res下的資源文件編譯成二進制文件,然後將其和上一步中的dex文件以及assets中的文件通過apkbuilder工具打包成apk文件
6、通過jarsigner對apk進行簽名
7、利用zipalign工具對apk進行字節對齊優化操作
 
 
 
轉載:https://www.cnblogs.com/xaf-dfg/p/6374423.html


1.自動簽名 
可以直接寫在build.gradle裏,如:

signingConfigs {
        develop {
            storeFile '/xxxxxx/xxx.jks'
            keyAlias 'xxxxxx'
            keyPassword 'xxxxxx'
            storePassword 'xxxxxx'
        }
    }

筆者習慣寫在配置文件裏,然後加入ignore方便後續更改 

è¿éåå¾çæè¿°

/**
 * 讀取簽名
 * @return
 */
def getSignProperty() {
    def Properties buildProperties = new Properties()
    buildProperties.load(new FileInputStream(file('../config/sign.properties')))
    return buildProperties
}

簽名配置sign.properties

STORE_PASSWORD=xxxxxx
KEY_PASSWORD=xxxxxx
KEY_ALIAS=xxxxxx
STORE_FILE=xxxxxx.jks

2.同時打出不同環境的包 
正常情況下一個項目可能同時有測試環境和正式環境 
如果每次打包都去改配置是非常繁瑣的,而且容易出錯 
建議在配置文件裏直接添加配置

productFlavors {
        buildDevelop {
            buildConfigField "boolean", "MODEL_DEV", "true"
            versionName = mVersionName
        }
        buildRelease {
            buildConfigField "boolean", "MODEL_DEV", "false"
            versionName = mVersionName
        }
    }

è¿éåå¾çæè¿°

如上所述,打包的時候會同時打出兩個不同的包,一個是測試環境一個是正式環境

3.輸出日誌 
記錄打包時候的時間,版本號以及Git提交的版本等等,方便日後審查

/**
 * 輸出日誌
 */
def buildLog(String output,String vName,String vCode) {
    File outputFile = new File(output)
    if(!outputFile.exists())
        outputFile.mkdirs()
    FileWriter fw = new FileWriter(output + File.separator + "log.txt")
    StringBuilder builder = new StringBuilder();
    builder.append("[構建時間]=" + buildTime("yy-MM-dd HH:mm"))
    builder.append("\r\n")
    builder.append("[版本編號]=" + vCode)
    builder.append("\r\n")
    builder.append("[版本名稱]=" + vName)
    builder.append("\r\n")
    builder.append("[提交記錄]=" + getGitVersion())
    fw.write(builder.toString())
    fw.flush();
    fw.close();
}

相關的函數

/**
 * 讀取Git日誌
 * @return
 */
def getGitVersion() {
    return 'git rev-parse --short HEAD'.execute().text.trim()
}

/**
 * 構建時間
 * @return
 */
def buildTime(String time) {
    def date = new Date()
    def formattedDate = date.format(time)
    return formattedDate
}

4.編譯構建完成之後最好備份一下mapping文件

build {
    doLast {
        //記錄日誌
        buildLog(mOutputs,mVersionName,mVersionProps['VERSION_CODE'])
        //複製文件
        copy {
            from "$buildDir/outputs/mapping"
            into mOutputs
        }
    }
}

最後的全局配置文件

apply plugin: 'com.android.application'

/**
 * 讀取版本配置
 */
def Properties mVersionProps = getVersionProperty();

/**
 * 讀取版本名
 */
def mVersionName = buildRelease() ? mVersionProps['VERSION_NAME'] : "build_" + buildTime('yyMMdd')

/**
 * 輸出目錄
 */
def mOutputs = "$rootDir/outputs/build_" + buildTime('yyMMdd')

android {

    signingConfigs {
        develop {
            def Properties buildSignProps = getSignProperty()
            storeFile file(buildSignProps['STORE_FILE'])
            keyAlias buildSignProps['KEY_ALIAS']
            keyPassword buildSignProps['KEY_PASSWORD']
            storePassword buildSignProps['STORE_PASSWORD']
        }
    }

    buildTypes {
        debug {
            applicationIdSuffix ".debug"
            buildConfigField "boolean", "MODEL_DEV", "true"
        }
        release {
            minifyEnabled true
            buildConfigField "boolean", "MODEL_DEV", "false"
            signingConfig signingConfigs.develop

            zipAlignEnabled true
            //去掉無用資源
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    //讀取版本配置
    compileSdkVersion 23
    buildToolsVersion "23.0.2"
    defaultConfig {
        applicationId "cn.byhook.main"
        minSdkVersion 9
        targetSdkVersion 23
        versionCode Integer.valueOf(mVersionProps['VERSION_CODE'])
        versionName = mVersionName
    }

    dexOptions {
        javaMaxHeapSize "4g"
    }

    lintOptions {
        checkReleaseBuilds false
        abortOnError false
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }

    productFlavors {
        /*_$ { variant.productFlavors.get(0).name }
        $ { variant.buildType.name }*/
        buildDebug {
            buildConfigField "boolean", "MODEL_DEV", "true"
            versionName = "Local Version"
        }
        buildDevelop {
            buildConfigField "boolean", "MODEL_DEV", "true"
            versionName = mVersionName
        }
        buildRelease {
            buildConfigField "boolean", "MODEL_DEV", "false"
            versionName = mVersionName
        }
    }


    if (buildRelease()) {
        android.variantFilter { variant ->
            if (variant.buildType.name.equals('release')) {
                variant.getFlavors().each() { flavor ->
                    if (flavor.name.equals('buildDebug')) {
                        variant.setIgnore(true);
                    }
                }
            }
        }
    }

    //輸出文件配置
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def outputFile = output.outputFile
            if (outputFile != null && outputFile.name.endsWith('.apk')) {
                if ("release".equals(variant.buildType.name)) {
                    if ("buildDevelop".equals(variant.productFlavors.get(0).name)) {
                        output.outputFile = new File(
                                mOutputs,
                                "Main_${buildTime("yyMMddHHmm")}_dev.apk")
                    } else if ("buildRelease".equals(variant.productFlavors.get(0).name)) {
                        output.outputFile = new File(
                                mOutputs,
                                "Main_${buildTime("yyMMddHHmm")}.apk")
                    }
                } else {
                    output.outputFile = new File(
                            outputFile.parent,
                            "app-debug.apk")
                }
            }
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    testCompile 'org.robolectric:robolectric:3.1'
    compile project(':Exlibrary')
}

/********************************************************************
 * 打包腳本
 ********************************************************************/

/**
 * 構建版本
 * @return
 */
def getVersionProperty() {
    def Properties buildProps = new Properties()
    buildProps.load(new FileInputStream(file('../config/version.properties')))
    return buildProps;
}

/**
 * 讀取簽名
 * @return
 */
def getSignProperty() {
    def Properties buildProperties = new Properties()
    buildProperties.load(new FileInputStream(file('../config/sign.properties')))
    return buildProperties
}

/**
 * 構建時間
 * @return
 */
def buildTime(String time) {
    def date = new Date()
    def formattedDate = date.format(time)
    return formattedDate
}

/**
 * 是否發佈
 * 發佈爲真
 * 版本號自增
 * @return
 */
def buildRelease() {
    return false
}

/**
 * 讀取Git日誌
 * @return
 */
def getGitVersion() {
    return 'git rev-parse --short HEAD'.execute().text.trim()
}

/**
 * 輸出日誌
 */
def buildLog(String output,String vName,String vCode) {
    File outputFile = new File(output)
    if(!outputFile.exists())
        outputFile.mkdirs()
    FileWriter fw = new FileWriter(output + File.separator + "log.txt")
    StringBuilder builder = new StringBuilder();
    builder.append("[構建時間]=" + buildTime("yy-MM-dd HH:mm"))
    builder.append("\r\n")
    builder.append("[版本編號]=" + vCode)
    builder.append("\r\n")
    builder.append("[版本名稱]=" + vName)
    builder.append("\r\n")
    builder.append("[提交記錄]=" + getGitVersion())
    fw.write(builder.toString())
    fw.flush();
    fw.close();
}

build {
    doLast {
        buildLog(mOutputs,mVersionName,mVersionProps['VERSION_CODE'])
        copy {
            from "$buildDir/outputs/mapping"
            into mOutputs
        }
    }
}

task mak{
    buildLog(mOutputs,mVersionName,mVersionProps['VERSION_CODE'])
}

打包只需終端輸入

//--info或者--debug輸出詳細信息,方便出錯時候定位錯誤
gradle clean
gradle build --info

è¿éåå¾çæè¿°

輸出

è¿éåå¾çæè¿°

小結一下,方便以後打包處理更爲方便,當然Gradle的強大之處遠不止如此

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