2014-03-25 25 views
1

我需要通過添加第二個簽名來對我的APK進行後期處理,所以我想了解如何在此時進入構建過程。我的第一次嘗試,gradle android:post-process APK

task doubleSign { 
    if (signing.androidBuildExists) { 
    android.buildTypes.all { type -> 
     tasks.("assemble${type.name.capitalize()}").finalizedBy doDoubleSign 
    } 
    } 
} 

沒關係罰款。但是如果install*任務中的任何一個都執行完畢,那麼我很驚訝,assemble*不在依賴關係樹中。所以接下來我嘗試添加該行,

tasks.("install${type.name.capitalize()}").dependsOn doDoubleSign 

但是,gradle告訴我該任務不存在!

> Could not find property 'installDebug' on task set. 

謝謝。

編輯:添加完整的解決方案供參考。當執行該代碼,因爲Android插件在afterEvaluate階段創建其任務

class DoubleSign extends DefaultTask { 
    DoubleSign() { 
    outputs.upToDateWhen { false } 
    } 

    File signScript = new File(project.androidBuild + '/sign.sh') 

    File inputFile 
    File keystore; 

    @TaskAction 
    void sign() { 
    List<String> args = new ArrayList<String>(); 
    args.add(signScript.toString()); 
    args.add(inputFile.toString()); 
    args.add(keystore.toString()); 


    Process process = new ProcessBuilder(args).redirectErrorStream(true).start(); 
    BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream())); 
    String line; 
    while ((line = input.readLine()) != null) { 
     System.out.println(line); 
    } 
    input.close(); 
    } 
} 

... 

afterEvaluate { 
    android.applicationVariants.all { variant -> 
    println "outputFile=" + variant.outputFile 
    if (variant.name.equals("debug")) { 
     // only do for debug builds 
     def signingTask = tasks.create(name: "double${variant.name.capitalize()}Sign", type: DoubleSign) 
     signingTask.inputFile = new File(variant.outputFile.toString().replace(".apk", "-unaligned.apk")) 
     signingTask.keystore = new File(project.androidBuild + '/keystore.jks') 

     signingTask.dependsOn variant.packageApplication 
     variant.zipAlign.dependsOn signingTask 
    } 
    } 
} 
+0

Android不會兌現第二個簽名。你期望通過這個獲得什麼? – CommonsWare

+0

我們正在對APK進行自己的驗證。我們有一個自定義固件,需要該應用程序由開發人員和我們的「應用程序商店」簽名。 –

回答

4

installDebug將不存在。

你應該做的:

android { 
    applicationVariants.all { variant -> 
    if (!variant.isSigningReady()) { 
     // only add double signing on variants that are signed with 
     // default signing method. 
     return 
    } 

    // get output file 
    def outputFile = variant.outputFile 

    // add new signing task. 
    def signingTask = project.tasks.create("double${variant.name}Sign", MyCustomSigning) 
    // configure task 
    signingTask.inputFile = outputFile 
    // create the final apk name using baseName to guarantee it's unique. 
    signingTask.outputFile = new File(project.buildDir, "apks/${project.name}-${variant.baseName}-2sign.apk") 

    // configure the task to be run after the default signing task. 
    signingTask.dependsOn variant.packageApplication 

    // configure zip align task to use the output of the 2nd signing task, 
    // and also to run after 2nd signing task. 
    variant.zipAlign.inputFile = signingTask.outputFile 
    variant.zipAlign.dependsOn signingTask 
    } 
} 

請注意,如果你不運行的zipalign(但實際上你應該),你必須調整結束,使variant.assemble取決於您的簽名任務,而不是和將簽名任務的輸出設置爲variant.outputFile,以便從命令行或IDE進行部署仍然有效。

對於實際簽名,您將使用註釋執行自定義任務,以便只在輸入文件實際更改時才運行。

class MyCustomSigning extends DefaultTask { 
    @InputFile 
    File inputFile 

    @OutputFile 
    File outputFile 

    @TaskAction 
    void sign() { 
    // call script to sign inputFile into outputFile 
    ... 
    } 
} 
+0

欣賞答案,但我迷失在如何掛在實際的簽名。我有一個腳本,將添加第二個簽名,然後重新zipalign。我想在最終的APK組裝完成後將其掛鉤。是的,如果它可以完成所有的事情,那會很棒。 –

+0

最好讓Gradle zipalign只專注於簽名。我添加了一個自定義任務的例子。 –

+0

再次感謝提示。在經歷了一些痛苦後,我得到了一個解決方案我會將它發佈在我的答案中供參考。 –

0

即使這個問題已經得到解答,我想分享最適合我的解決方案。

所有我需要的是一個合適的鉤子後處理完成完成的apk。爲此,我使用hook「assemble.doLast」:

android { 
    /* ... */ 

    applicationVariants.all { variant -> 
     variant.assemble.doLast { 
      variant.outputs.each { output -> 
       File apk = output.outputFile 
       // Post process apk 
      } 
     } 
    } 
} 
相關問題