Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android studio 2.2 compress all so files in built apk

Tags:

android

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?

like image 229
Brant Avatar asked Oct 14 '16 07:10

Brant


People also ask

How to make debug APK in Android Studio?

To start debugging an APK, click Profile or debug APK from the Android Studio Welcome screen. Or, if you already have a project open, click File > Profile or Debug APK from the menu bar. In the next dialog window, select the APK you want to import into Android Studio and click OK.

Can I build APK without Android Studio?

Check out the official docs - Build your app from the commandline. You can use gradle commands depending on which variant you want. For example, ./gradlew installDebug will make a debug apk and load it onto a connected device (though it won't open it like Android Studio does).

How to enable build variant in Android Studio?

By default, Android Studio builds the debug version of your app, which is intended for use only during development, when you click Run. To change the build variant Android Studio uses, select Build > Select Build Variant in the menu bar.


1 Answers

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.

like image 155
recih Avatar answered Sep 18 '22 10:09

recih