【问题标题】:android studio 2.2 compress all so files in built apkandroid studio 2.2 压缩内置apk中的所有so文件
【发布时间】:2017-02-23 12:27:07
【问题描述】:

更新 android studio 和插件后,新构建的 apk 在启动时遇到了令人费解的原生问题,我发现 armeabi/armeabi-v7a 所以文件从 200KB 压缩到 10KB。虽然旧的 android studio 无法做到这一点。

Android Studio 版本:2.2(windows 64bit) Gradle 版本:2.14.1 安卓插件版本:2.2.0

我阅读了 Android Plugin for Gradle 发行说明:

通过采用新的默认打包管道来提高构建性能,该管道在一项任务中处理压缩、签名和压缩对齐。您可以通过将 android.useOldPackaging=true 添加到 gradle.properties 文件来恢复使用旧的打包工具。使用新的打包工具时,zipalignDebug 任务不可用。但是,您可以通过调用 createZipAlignTask(String taskName, File inputFile, File outputFile) 方法自己创建一个。

我使用了android.useOldPackaging=true,但是不起作用,我发现优化发生在stripDebugSymbol中:

原始库:

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

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

我尝试'assembleDebug --exclude-task transformNative_libsWithStripDebugSymbolForDebug',这将导致apk中没有。

那么如何防止gradle插件优化这个呢?

【问题讨论】:

    标签: android


    【解决方案1】:

    更新:使用官方doNotStrip选项,https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.PackagingOptions.html

    感谢韦恩蔡的回答。

    此外,要禁用所有 so 文件的剥离,您可以在 build.gradle 中添加以下内容:

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

    旧答案:

    我遇到了同样的问题,在网上找不到任何官方方法来禁用这个自动剥离功能。

    幸运的是,我终于在 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)
        }
    }
    

    希望这能解决您的问题。

    【讨论】:

    • 这似乎不适用于 gradle-experimental:0.8.2 插件,因为实验性插件似乎不支持 applicationVariants。有什么建议吗?
    • 抱歉@Swampie,从未尝试过 gradle-experimental 插件。
    • 那么,如何使用 PackagingOptions 仅用于调试构建?
    【解决方案2】:

    packagingOptions 中有一个未记录的方法 'doNotStrip',只需在 build.gradle 中添加以下行

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

    更新:它在 2.3 文档中。

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题,对我有用的是重置全局 Android 工作室设置以及特定于项目的设置。为此,我刚刚完成了这些步骤:

      1. 克隆 android studio 项目,得到一个干净的副本。
      2. 删除~/.AndroidStudio2.2/(在Linux上)、c:\user\yourname\.AndroidStudio2.2(在Windows上)

      3. 启动 Android Studio 时不要导入任何设置。

      可能不是解决这个问题的最优雅的方法,但它对我有用。

      【讨论】:

        【解决方案4】:

        这是我对@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)
        }
        

        【讨论】:

          猜你喜欢
          • 2016-10-16
          • 1970-01-01
          • 2014-02-10
          • 2014-06-13
          • 2012-08-05
          • 1970-01-01
          • 1970-01-01
          • 2015-11-14
          • 2020-10-25
          相关资源
          最近更新 更多