Difference between D8 and R8 android - android

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.

Related

What is the difference between Proguard and R8?

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

Build speed is too slow after adding "android.enableD8.desugaring=true"

I have added android.enableD8.desugaring to solve some issues.
However, the build speed slowed down too much. (3min -> 20min)
Question.
What is android.enableD8.desugaring?
What is the operating principle of android.enableD8.desugaring?
Is it a factor to slow down the build?
Self Answer
The meaning of "android.enableD8.desugaring=true" should be interpreted separately.
d8 : d8 is a command line tool that Android Studio and the Android Gradle Plugin use to compile your project's Java bytecode into DEX bytecode that runs on Android devices, and it allows you to use Java 8 language features in your app's code.
"desugaring = true" : You can use Java 8 language features. "Java 8 language features." It is understood as a lambda expression.
I guess d8 might be slower when compiling "Java 8 language features."
Reference
: d8 | Android Developers

Compile with D8

I want to use the recently introduced D8 compiler from Google to build a dex file.
Unfortunately, I didn't find the jar executable in the build-tools folder (like the dx tool).
Does anyone know where it's located instead?
Thanks in advance.
There is no D8.jar anywhere in build-tools. D8 is distributed as a maven artifact instead. It can be downloaded from https://maven.google.com. The artifact is named com.android.tools:r8 because D8 is a part of the R8 project. The jar contains both R8 and D8 commandline interfaces, so, in theory, it can be downloaded and used from a commandline like:
java -cp r8.jar:<...dependency jars> com.android.tools.r8.D8 <D8 arguments here>
java -cp r8.jar:<...dependency jars> com.android.tools.r8.R8 <R8 arguments here>
However this artifact jar has a lot of dependencies and if you want to use it outside of the gradle-based build then it is easier to build r8/d8.jar executable jars from the sources by yourself. The instruction how to do it is at https://r8.googlesource.com/r8/. The resulting jars are self-contained (all deps bundled in).
The Android Gradle plugin (and, therefore, Android Studio) doesn't depend on the com.android.tools:r8. R8/D8 classes are bundled into com.android.tools.build:builder (one of the libraries that gradle plugin consists of) instead.
D8 dexer has become the default compiler in #AndroidStudio 3.1
Expect faster and smarter app compilation
Faster, smarter app compilation is always a goal for the Android tools teams. That's why we previously announced D8, a next-generation dex compiler. D8 runs faster and produces smaller .dex files with equivalent or better runtime performance when compared to the historic compiler - DX
Please see comparition beetween DX vs D8 :
You can always revert to DX for now via this setting in your project's gradle.properties file:
android.enableD8=false

Eclipse to Android Studio Import

I am moving all my source codes to AS as suggested by Android official website. However, the experience is not very good. It is very sluggish as described here. But this is not my ultimate problem for now.
I have resolved many problems such as updating the compileSdkVersion to 23 so that 99 errors of this kind:
Error:(13) Error retrieving parent for item: No resource found that matches the given name 'android:TextAppearance.Material.Inverse'.
could be rectified. But the problems keep on shooting up as I go. Now I have this 64k Dex issue.
Error:The number of method references in a .dex file cannot exceed 64K.
Learn how to resolve this issue at https://developer.android.com/tools/building/multidex.html
I never had this Dex issue while using Eclipse. The source code I have in AS is exactly the same as when it was in Eclipse. The only differences are those gradle changes needed only to work on AS. Any idea why this sudden Dex issue? if I set multiDexEnabled to true, what are the implications?
First of all, make sure you rebuild project, after importing (Build - Clean, Builde - Rebuild Probject). Fixing this issue with limitation methods reference:
android {
defaultConfig {
...
// Enabling multidex support.
multiDexEnabled true
}
...
}
dependencies {
compile 'com.android.support:multidex:1.0.0'
}
And also update you Application.class in java to support MultiDex. See full information here!
UPDATE:
This options ignore on Eclipse, because methods references limit can be calculated from environment (like AS in our case). Why this options doesn't include in Gradle build - still question...
Android application (APK) files contain executable bytecode files in the form of Dalvik Executable (DEX) files, which contain the compiled code used to run your app. The Dalvik Executable specification limits the total number of methods that can be referenced within a single DEX file to 65,536—including Android framework methods, library methods, and methods in your own code. In the context of computer science, the term Kilo, K, denotes 1024 (or 2^10). Because 65,536 is equal to 64 X 1024, this limit is referred to as the '64K reference limit'.
Source AS Doc
I suspect your dex error is a result of the growth of a library, but without more info, this is hard to debug. The newest version of Android Studio (2.2) provides an APK analyzer tool that makes the dex limit more transparent.
When using Google Play services APIs you should double check to make sure that you're only including the ones used with these directives
compile 'com.google.android.gms:play-services-fitness:9.6.1'
rather than including everything (full list).
If you need all the libraries you're already depending on then, this is typically resolved by enabling multidex in your development environment (requiring development using a device or emulator with L or greater), but then using minificationEnabled in your release builds such that multidex isn't required in your release APK. This results in a combination of fast debug builds and non-multidex your release builds to prevent slow startup times for your release build.
A bit more info:
When you use native multidex in debug builds (requires minSdk set to L or greater) it results in faster incremental builds because modules and libraries deploy as separate dex files and less processing between deploys.
When you use minificationEnabled in your release build it often eliminates the need for the second dex file because methods from your dependendencies that you don't use are trimmed. This typically results in a single dex nullifying the negative effects of multidex (copying the N+1 dex files on app initialization for < version L devices).
Multidex issue occurs when you use lots of libraries in your project. If your app's code have more than 64k methods then it happens.
When your application and the libraries it references reach a certain
size, you encounter build errors that indicate your app has reached a
limit of the Android app build architecture.
You can refer some links like :
How to enable multidexing with the new Android Multidex support library
http://www.rapidvaluesolutions.com/tech_blog/multidex-issue-or-building-application-over-65k-methods/
https://mutualmobile.com/posts/dex-64k-limit-not-problem-anymore-almost

Android & Proguard?

I am trying to use progurard with my android applications.
The proguardGui accepts an input, and an output, the input requires a jar file. but the APK file for android doesn't contain any jar?
I tried passing the apk file, and also the dex file inside the apx, but proguard doesn't accept them as an input. proguard only accepts jars, ears, wars, zips so how can i use the proguard gui with my android application?
I detailed complete instructions on how to do it here: http://www.androidengineer.com/2010/07/optimizing-obfuscating-and-shrinking.html
Basically, you have to first set up an Ant build for your Android project, which is relatively painless. Then, you add in the ProGuard Ant target between the Java compilation step and the DEX step. Remember, ProGuard only works on Java bytecode, and Android uses the Dalvik JVM which uses .dex bytecode, so that's why it happens between those two steps.
Actually the Android SDK already integrates ProGuard.
You only need to uncomment the line "proguard.config=....." in the file project.properties (created or updated by Android SDK 17 or higher), in order to enable ProGuard.
Source: ProGuard examples -> a complete Android Application

Categories

Resources