简体   繁体   English

android studio 2.2压缩所有内置apk中的文件

[英]android studio 2.2 compress all so files in built apk

After update android studio and plugins, new built apk meets puzzling native problem when launch, I found armeabi/armeabi-v7a so files compressed from 200KB to 10KB. 更新android studio和插件后,新建的apk在启动时遇到令人费解的本机问题,我发现armeabi / armeabi-v7a所以文件压缩从200KB到10KB。 While old android studio can't do this. 虽然旧的android工作室无法做到这一点。

Android Studio Version:2.2(windows 64bit) Gradle Version:2.14.1 Android Plugin Version:2.2.0 Android Studio版本:2.2(Windows 64位)Gradle版本:2.14.1 Android插件版本:2.2.0

I read the Android Plugin for Gradle Release Notes: 我阅读了Gradle Release Notes的Android插件:

Improves build performance by adopting a new default packaging pipeline which handles zipping, signing, and zipaligning in one task. 通过采用新的默认打包管道来改进构建性能,该管道在一个任务中处理压缩,签名和zipaligning。 You can revert to using the older packaging tools by adding android.useOldPackaging=true to your gradle.properties file. 您可以通过将android.useOldPackaging = true添加到gradle.properties文件来恢复使用旧的打包工具。 While using the new packaging tool, the zipalignDebug task is not available. 使用新的打包工具时,zipalignDebug任务不可用。 However, you can create one yourself by calling the createZipAlignTask(String taskName, File inputFile, File outputFile) method. 但是,您可以通过调用createZipAlignTask(String taskName,File inputFile,File outputFile)方法自己创建一个。

I used android.useOldPackaging=true, but it doesn't work, and I found the optimization happens in stripDebugSymbol: 我使用android.useOldPackaging = true,但它不起作用,我发现优化发生在stripDebugSymbol中:

raw libs: 原始库:

+---armeabi | + --- armeabi | libsecuritysdk-3.1.27.so 210KB | libsecuritysdk-3.1.27.so 210KB | +---armeabi-v7a | + --- armeabi-v7a | libsecuritysdk-3.1.27.so 233KB | libsecuritysdk-3.1.27.so 233KB | ---x86 libsecuritysdk-3.1.27.so 195KB --- x86 libsecuritysdk-3.1.27.so 195KB

intermediates&apk: YourProject\\example\\build\\intermediates\\transforms\\stripDebugSymbol\\debug\\folders\\2000\\1f\\main +---armeabi | 中间体和apk:YourProject \\ example \\ build \\ intermediates \\ transforms \\ stripDebugSymbol \\ debug \\ folders \\ 2000 \\ 1f \\ main + --- armeabi | libsecuritysdk-3.1.27.so 9.06KB | libsecuritysdk-3.1.27.so 9.06KB | +---armeabi-v7a | + --- armeabi-v7a | libsecuritysdk-3.1.27.so 9.07KB | libsecuritysdk-3.1.27.so 9.07KB | ---x86 libsecuritysdk-3.1.27.so 9.06KB --- x86 libsecuritysdk-3.1.27.so 9.06KB

I try 'assembleDebug --exclude-task transformNative_libsWithStripDebugSymbolForDebug',this will lead to no so in apk. 我尝试'assembleDebug --exclude-task transformNative_libsWithStripDebugSymbolForDebug',这将导致apk中没有。

So how to prevent gradle plugin optimize this? 那么如何防止gradle插件优化呢?

Update : Use the official doNotStrip option, https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.PackagingOptions.html 更新 :使用官方的doNotStrip选项, httpsdoNotStrip

Thanks to Wayne Cai's answer. 感谢Wayne Cai的回答。

In addition, to disable strip on all so files, you can add following to your build.gradle : 此外,要在所有so文件上禁用strip,可以在build.gradle添加以下build.gradle

packagingOptions{
    doNotStrip "**/*.so"
}

Old answer: 老答案:

I had the same problem, and can't find any official method to disable this auto strip feature on the internet. 我有同样的问题,并没有找到任何官方方法来禁用互联网上的这个自动剥离功能。

Fortunately, I finally got this work around in build.gradle: 幸运的是,我终于在build.gradle中完成了这项工作:

applicationVariants.all { variant ->
    def copyUnstripedJniLibTask = tasks.create(name: "copyUnstripedJniLibFor${variant.name.capitalize()}") << {
        def destDirRoot = new File(projectDir, "build/intermediates/transforms/stripDebugSymbol/${variant.dirName}/folders/")
        if (!destDirRoot.isDirectory()) return

        // the folder contains final so files is something like "stripDebugSymbol/variantName/debug/folders/2000/1f/main/lib/",
        // I don't know how to generate the "2000/1f" part, so I have to search for it.
        // If you got better idea, please comment.
        def list = FileUtils.listFiles(destDirRoot, FileFilterUtils.suffixFileFilter("so"), FileFilterUtils.trueFileFilter());
        if (list.size() <= 0) return

        def destDir = list[0].getParentFile().getParentFile()
        def srcDir = new File(destDir.getAbsolutePath().replace("stripDebugSymbol", "mergeJniLibs"))
        println "Copying unstriped jni libs ..."
        println "    from ${srcDir}"
        println "    to ${destDir}"

        // Copy the unstriped so files to overwrite the striped ones.
        FileUtils.copyDirectory(srcDir, destDir)
    }

    def transformNativeLibsTask = project.tasks.findByName("transformNative_libsWithStripDebugSymbolFor${variant.name.capitalize()}")
    if (transformNativeLibsTask) {
        transformNativeLibsTask.finalizedBy(copyUnstripedJniLibTask)
    }
}

Hope this will solve your problem. 希望这能解决你的问题。

There's an undocumented method 'doNotStrip' in packagingOptions, just add following lines in your build.gradle 在packagingOptions中有一个未记录的方法'doNotStrip',只需在build.gradle中添加以下行

packagingOptions{
    doNotStrip "*/armeabi/*.so"
    doNotStrip "*/armeabi-v7a/*.so"
    doNotStrip "*/x86/*.so"
}

update: it's in 2.3 document. 更新:它在2.3文档中。

I had the same problem and what worked for me was to reset global Android studio settings as well as project specific. 我有同样的问题,对我有用的是重置全球Android工作室设置以及项目特定。 To do so I just done those steps: 为此,我刚刚完成了这些步骤:

  1. Clone the android studio project, to have a clean copy. 克隆android工作室项目,有一个干净的副本。
  2. Remove ~/.AndroidStudio2.2/ (on Linux), c:\\user\\yourname\\.AndroidStudio2.2 (on Windows) 删除~/.AndroidStudio2.2/ (在Linux上), c:\\user\\yourname\\.AndroidStudio2.2 (在Windows上)

  3. Do not import any settings when starting Android studio. 启动Android Studio时不要导入任何设置。

Probably not the most elegant way to solve this, but it works for me. 可能不是解决这个问题最优雅的方法,但它对我有用。

Here's my variation of @recih's answer which works with the experimental plugin: 这是@ recih的答案的变体,它适用于实验性插件:

tasks.whenTaskAdded { task ->

    if (task.name.startsWith('transformNative_libsWithStripDebugSymbolFor')) {
        task.finalizedBy copyUnstripedJniLibTask
    }
}

task copyUnstripedJniLibTask() << {

    def destDirRoot = new File(projectDir, "build/intermediates/transforms/stripDebugSymbol/unprotected/debug/folders/")
    if (!destDirRoot.isDirectory()) return

    def destDir = destDirRoot
    def srcDir = new File(destDirRoot.getAbsolutePath().replace("stripDebugSymbol", "mergeJniLibs"))

    println "Copying unstriped jni libs ..."
    println "    from ${srcDir}"
    println "    to ${destDir}"

    // Copy the unstripped so files to overwrite the striped ones.
    FileUtils.copyDirectory(srcDir, destDir)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM