6

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. While old android studio can't do this.

Android Studio Version:2.2(windows 64bit) Gradle Version:2.14.1 Android Plugin Version:2.2.0

I read the Android Plugin for Gradle Release Notes:

Improves build performance by adopting a new default packaging pipeline which handles zipping, signing, and zipaligning in one task. You can revert to using the older packaging tools by adding android.useOldPackaging=true to your gradle.properties file. While using the new packaging tool, the zipalignDebug task is not available. However, you can create one yourself by calling the createZipAlignTask(String taskName, File inputFile, File outputFile) method.

I used android.useOldPackaging=true, but it doesn't work, and I found the optimization happens in stripDebugSymbol:

raw libs:

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

intermediates&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

I try 'assembleDebug --exclude-task transformNative_libsWithStripDebugSymbolForDebug',this will lead to no so in apk.

So how to prevent gradle plugin optimize this?

Brant
  • 221
  • 1
  • 3
  • 7

4 Answers4

6

Update: Use the official doNotStrip option, https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.PackagingOptions.html

Thanks to Wayne Cai's answer.

In addition, to disable strip on all so files, you can add following to your 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:

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.

recih
  • 61
  • 4
4

There's an undocumented method 'doNotStrip' in packagingOptions, just add following lines in your build.gradle

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

update: it's in 2.3 document.

Wayne Cai
  • 768
  • 6
  • 3
1

I had the same problem and what worked for me was to reset global Android studio settings as well as project specific. To do so I just done those steps:

  1. Clone the android studio project, to have a clean copy.
  2. Remove ~/.AndroidStudio2.2/ (on Linux), c:\user\yourname\.AndroidStudio2.2 (on Windows)

  3. Do not import any settings when starting Android studio.

Probably not the most elegant way to solve this, but it works for me.

kamillo
  • 131
  • 7
0

Here's my variation of @recih's answer which works with the experimental plugin:

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)
}
Swampie
  • 165
  • 1
  • 1
  • 9