2014-03-25 26 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 
      } 
     } 
    } 
} 
相关问题