I have a pretty large apk file, and I'm trying to reduce its size. Already used all the common techniques, such as Proguard and image compression. Still, the apk is quite large - about 25mb.
Wikipedia says that:
APK files are a type of archive file, specifically in zip format packages based on the JAR file format, with .apk as the filename extension.
I've recently noticed that if I'll unzip the apk (Android Studio's artifact output), re-zip it using 7-Zip and sign it, then the size magically decreases by 2.5mb (to ~22.5mb). I'm able to upload it to Play, install and run it without an issue.
And here're my questions:
Thanks!
Edit [5/13/2015]:
Compressing the APK contents worked well for me. However, I had to be cautious with raw resources (typically placed under res/raw). For example, invoking Resources#openRawResourceFd with a compressed resource as parameter will end with the following exception:
java.io.FileNotFoundException: This file can not be opened as a file descriptor; it is probably compressed
Therefore, remember to exclude raw resources from compression.
I'm able to upload it to Play, install and run it without an issue.
Only on the devices that you tried. I suspect, for example, that you did not try an API Level 1 device.
Is there any data that wiped during unzip & rezip process?
We have no way of answering that question. The only person who can answer that question is you, as you are the one who did your specific "unzip & rezip process". You should be able to analyze your two ZIP files and see where the differences are, such as higher compression ratios on certain file types, files that got lost by the way you ran your "rezip process", etc.
In general, the only thing that should be lost would be any zipalign-ing, if you did not reapply that yourself.
If no, why aapt (the one that Android Studio uses) packages files in so inefficient manner?
Size is not the only consideration. Speed of access is another, as many things (e.g., resources, assets) are kept in the APK file and read out of there on the fly as needed. Memory consumption for the decompression logic is yet another consideration.
Android devices, particularly early ones, have many constraints, disk space being but one of them. Even though some of these constraints have been relaxed as hardware has advanced, the build tools are dedicated to backwards compatibility -- you should be able to write an app today that can run on an API Level 1 device, for example. That puts constraints on the tools in terms of how they can change over time.
What could go wrong if I'll use this method?
Your app may not work on Android devices, where their runtimes are set up making certain assumptions about the APK ZIP compression algorithms use. Ideally, your app will run fine everywhere. At minimum, you would want to test your app on every API level that you support -- older API levels may be somewhat more likely to "cut corners" and make assumptions that your approach will invalidate.
Assuming you are forcing 7zip to use its zip compatible mode (-tzip
) then this is an entirely valid operation (though as @CommonsWare notes, there is a tiny possibility that you are opening yourself up to some buggy implementations of the zip unpacking routine on some phones).
The reason that you are able to get a size reduction are twofold:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With