[Gradle] 如何在android項目中對純Java module啓用proguard

如何在android項目中對純Java module使用release/debug build並啓用proguard?這裏提供一種方法,儘管不是很「好看」,可是可用。java

假設app模塊依賴lib模塊,lib模塊是一個純Java模塊(apply plugin: 'java')。整個過程能夠分紅兩步。android

引入Proguard

在lib模塊的build.gradle裏添加如下代碼app

import proguard.gradle.ProGuardTask

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'net.sf.proguard:proguard-gradle:5.3.3'
    }
}

task proguardFiles(type: ProGuardTask, dependsOn: compileJava) {
    // 讓jar這個task依賴於本task,後文會說明
    tasks.jar.dependsOn.add(proguardFiles)

    println "proguarding"

    // 配置ProGuardTask
    printmapping "$buildDir/mapping.txt"
    configuration 'proguard-rules.pro'
    libraryjars files(configurations.compile.findAll {}.collect())
    injars sourceSets.main.output
    // 設置輸出路徑,注意這裏輸出物爲文件(不是默認的jar)
    outjars "$buildDir/libs/${project.name}"
    
    // 清除上次的生成物
    delete "$buildDir/libs/${project.name}"

    // 在本task的execute階段,將混淆後的class文件替換正常class文件
    doLast {
        println "copying product:${sourceSets.main.output.classesDir}"

        // 刪除原有的class文件
        delete "${sourceSets.main.output.classesDir}"
        // 將混淆class文件複製過去
        copy {
            from "$buildDir/libs/${project.name}"
            into "${sourceSets.main.output.classesDir}"
        }
    }
}

這裏作了幾件事情:maven

  1. 定義proguard task,令jar這個java task依賴於它。即proguard task運行完畢後才運行jar。ide

  2. 使用文件替換的方式,在jar運行前替換掉class文件。函數

  3. 經過觀察gradle console的輸出,得知app在編譯時會運行jar task。通過1.2.兩步咱們能夠在正常編譯
    流程中插入proguard處理後的class文件。gradle

接下來看怎麼樣根據debug和release compile關閉或開啓proguard優化

引入debug/release

在lib模塊的build.gradle中加入以下代碼:ui

// 定義debug compile的回調函數
void onDebug() {
    println " ----- onDebug ----- "

    // 在debug模式下,關閉混淆優化等一系列操做
    proguardFiles.dontobfuscate()
    proguardFiles.dontoptimize()
    proguardFiles.dontshrink()
    proguardFiles.dontpreverify()
}
// 定義release compile的回調函數
void onRelease() {
    println " ----- onRelease -----"
}

而後在app的build.gradl中加入以下代碼:spa

tasks.whenTaskAdded { task ->
    if (task.name == 'preReleaseBuild') {
        // release build
        task.doLast {
            def taskProject = rootProject.subprojects.findAll {it.name == "lib"}
            taskProject[0].onRelease()
        }
    } else if (task.name == 'preDebugBuild') {
        // debug build
        task.doLast {
            def taskProject = rootProject.subprojects.findAll {it.name == "lib"}
            taskProject[0].onDebug()
        }
    }
}

這段代碼作了兩個事情:

  1. 監聽了task的添加流程,在'preReleaseBuild'和'preDebugBuild'的execute階段添加了代碼邏輯。

  2. 在'preReleaseBuild'和'preDebugBuild'執行完後,執行lib模塊中的onRelease或者onDebug方法。

綜上,實現了在android項目中對純Java module使用release/debug build並啓用proguard。

注:本文默認讀者具備gradle基礎知識。
注:附Java Plugin依賴圖:
https://docs.gradle.org/3.3/userguide/img/javaPluginTasks.png

相關文章
相關標籤/搜索