I want both ProGuard and R8 to perform code shrinking and optimization: I'm sure R8 after a year of development cannot be as cool as ProGuard after 15 years.
android.enableR8 flag enables R8 instead of ProGuard.
Is there any way to use both tools using official Android toolchain, i. e. Gradle with Android plug-in?
There is no supported way of running both R8 and ProGuard inside Android Studio. I suggest that you compare the results of the two shrinkers, and decide which one you want to stick with. If you see R8 producing larger output than ProGuard please let us know, by file a bug report using this link.
Related
I'm looking at my production builds and 50% of the build time is in the task minifyProductionReleaseWithR8. Looking at Google's guides for optimizing build speed there is nothing mentioned about R8. Generally, I'm working towards breaking out more modules to enable better build parallelization but I don't know if that will affect R8 minification time.
The new version of Android Studio (3.4) just came out and brings with it default support for R8 instead of Proguard. Could someone explain the key differences between the two and any apparent benefits to using R8?
The history of Android build process kept changing and the developers are constantly trying to make it more efficient concerning build time and generated .dex file sizes. So, throughout the history there has been many variation of the process of generating .dex files from .java files.
Before R8 or D8, the Android build process involved these four steps;
SourceCode(.java) ---javac---> Java Bytecode(.class) ---Proguard---> Optimized Java bytecode(.class) ---Dex---> Dalvik Optimized Bytecode(.dex)
Then, the Android developers decided to merge all the steps in between to 1 step called Jack&Jill for optimization. However, this was introduced in 2015 and abandoned in 2017 due to not being flexible enough to work with all the growing development tools.
Then, D8 was introduced, which is a reverting back to original 4 step build process, with an optimized Dex transform. This implementation produced better quality bytecode than dx, with fewer instructions and better register allocation.
Now to R8, which has a similar goal with Jack&Jill as a starting point, merging two of these build steps into one. The Proguard and Dex step. So, instead of first Proguard processing the .class file returning again .class files and Dex/D8 processor taking in .class and returning .dex files, R8 merges these two steps, and takes in .class files, returning .dex files. This tool is still getting better, trying to optimize the build process even more. So, it is smart to migrate your project to R8 now, as it is a still growing tool which will be the default build tool soon. (As can be seen by enabled by default in the upgrade of Android Studio(3.4))
Also, the developers in Google issue tracker are very fast in returning to the issues reported about R8, as they are hungry for feedback and want to perfect this tool.
It has been reported that using R8 produces smaller .dex files, and does a more efficient minification of removing unused classes. This is a plus and a minus in some way. It is a plus obviously because smaller size is always better(in programming!),it is a minus because you have to intricately go through your code, and detect your entry points and reimplement the keep rules in your proguard file accordingly, as R8 introduces a more aggressive minification than Proguard.
For more information you can look into this article which includes very detailed explanation on R8 vs. Proguard: https://www.guardsquare.com/en/blog/proguard-and-r8
Also, this official speech from Google I/O 2018 : https://www.youtube.com/watch?v=x9T5EYE-QWQ&t=1194s
Hope this helps,
ProGuard vs R8
History flow
ProGuard -> R8
// R8 is default optimizer of .class files from Android Studio v3.4
ProGuard[About] is open source product
R8 is a Google product
Target:
minify, shrinking
optimize
obfuscate, renaming
R8
R8 has better performance because convert .class directly into .dex without extra step (optimised .class)
R8 has better compatibility with Kotlin
As android studio introduced two new tools D8 and R8.
As per google documentation D8 is a dex tool and R8 is a progourd tool but as their explanation both are doing almost same thing like below:
D8 is a dexer that converts java byte code to dex code.
R8 is a java program shrinking and minification tool that converts java byte code to optimized dex code.
It seems both converts java byte code to dex code literally. So, Whats actually they are doing internally in case of converting dex code?
D8 dexer and R8 shrinker
D8->D8 is a dexer that converts java byte code to dex code.
R8->R8 is a java program shrinking and minification tool that converts java byte code to optimized dex code.
Android developers know that dex compilation is a key step in building an APK. This is the process of transforming .class bytecode into .dex bytecode for the Android Runtime (or Dalvik, for older versions of Android). The dex compiler mostly works under the hood in your day-to-day app development, but it directly impacts your app's build time, .dex file size, and runtime performance.
The R8 project uses depot_tools from the chromium project to manage dependencies. Install depot_tools and add it to your path before proceeding.
The R8 project uses Java 8 language features and requires a Java 8 compiler and runtime system.
New version number scheme following the SDK Tools revision number.
Support for true debug build. No need to change the value of debuggable in
the Android Manifest.
Incremental build will automatically insert debuggable==true while using
the "export signed/unsigned application package" will not.
If debuggable=true is set, then release builds will actually do a debug build.
Automatic Proguard support in release builds. Only need to have a proguard.config
property in default.properties that points to a proguard config file.
Completely rewritten Visual Layout Editor. This is very much a work in progress.
full drag and drop from palette to layout for all Layout classes.
Move widgets inside a Layout view, from one Layout view to another and from one layout file to another.
Contextual menu with enum/flag type properties.
New zoom controls.
I think the introduction of this blogpost is a great resource to answer that question: https://jakewharton.com/r8-optimization-staticization
R8 is a version of D8 that also performs optimization. It’s not a separate tool or codebase, just the same tool operating in a more advanced mode. Where D8 first parses Java bytecode into its own intermediate representation (IR) and then writes out the Dalvik bytecode, R8 adds optimization passes over the IR before its written out.
D8 processes each Java class file individually without looking at the entire program. This makes the conversion to DEX fast, since classes can be processed in parallel, and during development it allows fast recompilation when the code of a class is modified.
On the other hand, R8 (like ProGuard) reads in the entire application and makes changes and optimizations (e.g. inlining) that require knowing the entire class hierarchy. For instance, R8 will remove unused classes and methods ("tree shaking") and rename classes, methods and fields (except for the application's entry points).
In Android Studio 3.1, D8 has replaced DX as the tool that converts Java class files to DEX, but R8 has not been enabled yet.
Hi I developed one android library and Now I want to obfuscate it for redistribution. I develop my library with eclipse and android version 4.1.2. I tried obfuscating with eclipse and pro-guard. I do export and and also put proguard.config = proguard-project.text in project-properties but it not generating any jar file. It shows me result as its not allowing to library projects.
So I don't know how to obfuscating android library project. I need help regarding how to obfuscating of android library projects.
Need Help Thank you.
The Android SDK doesn't apply ProGuard to library projects; it only applies ProGuard to final applications (including their libraries). The latter is more effective in terms of shrinking, optimization, and obfuscation, because it can work on a larger body of code and it doesn't need to preserve the public API of the libraries.
If you want to distribute your library as an end-product, you can post-process it, as discussed in the ProGuard manual > Examples > A typical library.
Alternatively, DexGuard, ProGuard's commercial sibling for Android, can also process library projects out of the box.
(I am the developer of ProGuard and DexGuard)
In order to obfuscate your library what you need to do is:
Make sure gradle settings for lib module state minifyEnabled true .
run ./gradlew assemble{flavor}Release
After running headfirst into as many problems as there are permutations of the set of Android command-line tools, I finally managed to compile a mix of Scala and Java source code into a usable apk.
As many suggest, I used proguard to squeeze the Scala library through the dex tool. The problem is this:
BUILD SUCCESSFUL
Total time: 1 minute 29 seconds
One minute and a half. We're talking about an application with Hello-World complexity here. I don't think I can develop like that. I'm gonna need to take meditation classes.
This is the proguard configuration:
-injars ${out.absolute.dir}/classes:${scala-library.jar}(!META-INF/MANIFEST.MF,!library.properties)
-outjars ${out.absolute.dir}/classes.min.jar
-libraryjars ${android.jar}
-dontwarn
-dontoptimize
-dontobfuscate
-keep public class * extends android.app.Activity
Is there a way to speed up the proguard step?
Edit: I'm running this in a pretty decent dual-core, 3GB ram machine, on top of 64-bit Linux. A run of ant compile (scalac/javac) takes 3 seconds. A full ant install takes 1:30, as described above. It's the proguard step that "freezes", according to the output, most likely because of the scala/android runtime lib sizes.
Working via android Ant builds is probably not the right way to go about this.
The current "best advice" is to use SBT with the
proguard (https://github.com/siasia/xsbt-proguard-plugin) and
android (https://github.com/jberkel/android-plugin)
plugins.
ProGuard takes a lot longer to shrink the Scala 2.9.1 library than the Scala 2.8.1 library (54 seconds vs. 13 seconds, for 8.5 MB vs. 6.2 MB). Either the structure of the library classes has changed fundamentally, or some new classes are causing excessive computations. I'll have to figure out if ProGuard or its configuration can be improved for this case. For now, you might be able to work with Scala 2.8.1.
I'm assuming your ProGuard configuration also contains the required options for Android and for Scala, as discussed in the ProGuard manual. If you are using the regular Android build process, the input (classes, libs) and libraries (android.jar) are already specified for you in the Ant build file, and you don't need to specify them again in the ProGuard configuration file. Reading them twice will just take time and generate many warnings (which you have switched off completely -- it's safer to switch them off selectively).
If you have a rooted phone and only want to test on this you can install the scala libs directly on your phone so you don't need the proguard step anymore:
https://github.com/jrudolph/scala-android-libs