A few weeks ago I had a pleasure to visit first conference for mobile developers in my area — DevFest Baltics 2017. It was a huge success for organizers and all attendees, as it was sold out and had positive feedbacks. For more details about this event, you can check this publication.
One of the conference sponsors was ZeroTurnaround JRebel for Android. I heard about JRebel many times, but somehow never managed to try it myself and no one at work was interested enough to try it as well. I thought it’s time to do it and I will write here what I found out about this product.
Where should I start? On JRebel official page you can find a quick-start guide, basically, all you have to do is install the plugin, at the time of writing already 107411 users downloaded it. After you install it on your IDE, you will be asked for credentials so you can get 14-days trial period and you are good to go.
So here is some basic info about it straight from their official page — “JRebel for Android is an Android Studio and IntelliJ IDE plug-in that accelerates the development of Android applications by eliminating the time consuming full build, install and run cycle, saving hours of developer time annually.”
You will ask, why would I need such tool if I already use Android Studio’s “Instant Run”, well, as their official page states — JRebel offers much more plus Instant Run has his issues.
JRebel For Android and Instant Run are all about code or resources swapping. If APK is already installed on the device you just send small incremental patches that will be applied. So you save time by not rebuilding and packaging code parts that have not changed, fewer data pushed to the device over ADB and the dex2oat has a lot less work to do, compared to a full APK install.
There are three types of code swaps: hot, warm and cold swaps.
Hot-swap updates your app without new APK. It allows updating class bytecode in place, using the same class identity. This means that all objects could refer to an updated class and execute new code when their methods were called. But this swap is limited only to changing method bodies. This is done by adding stub methods that will be executed the next time the method is called.
Warm swap is useful for updating app resources. It updates apps resource files and restarts Activities/Fragments so you could see changes. JRebel preserves your Fragment state and back stack or even ViewPager current page. It is not instant, but for me applying changes without rebuilding app was 5 times faster and you don’t have to renavigate inside your app to find needed fragment and recreate its state.
Cold swap is used for structural changes that can not be supported by previous two. This swap requires app restart but it is still faster than rebuilding APK.
Depending on your Android Studio build preferences when you use Instant Run it will warm swap your code by default or hot swap it if you change this setting and always warm swaps your resources, on another hand JRebel will always use warm swaps if it’s possible so user could understand what is happening and what to expect. They even show toast about changes.
In table below you can see comparison when Instant Run and JRebel can apply warm swaps.
As you can see JRebel has more to offer for developers.
The second question in their FAQ is — “How does it work?” — “JRebel integrates with the JVM on the class loader level. It does not create any new class loaders, instead, it extends the existing ones with the ability to manage reloaded classes.
When a class is loaded JRebel will try to find a corresponding .class file for it. It will search from the classpath and from the places specified in the rebel.xml configuration file. If it finds a .class file JRebel instruments the loaded class and associates it with the found .class file. The .class file timestamp is then monitored for changes in the loaded class and updates are propagated through the extended class loader, to your application.”
As for development tools and instruments, it supports most of Annotation processing libraries, Dagger/Dagger 2, IcePick, ButterKnife etc. but when an unsupported annotation processor is detected, JRebel for Android will disable the incremental Java compilation. The plugin is available for Android Studio and IntelliJ Idea. Idea version is more stable because new features come to Android Studio branch first.
You can swap code during debug sessions with it!
“Debug an application directly by using “Debug with JRebel for Android” to install the application or to attach it to a running process. You can continue updating the code and resources when a debugger is attached to get instant insight into the application.” Here I had issues with old devices, they just hanged on me. But updating code during debugging is amazing. Previously I used debug feature “Evaluate Expression” to “swap” code (actually just ran multiple times different code until I get a correct result out of it and relaunch app).
For sure it has not only pros but cons also. If you wondered about Kotlin support, it does support it —
“JRebel for Android works on a bytecode level. This way we can support all JVM languages while keeping ART and Dalvik compatibility. Write your apps with Gradle integration in any language: Kotlin, Scala, Groovy or Java.” But incremental compiler won’t work with Kotlin compilation. JRebel for Android still needs to do less work to apply changes. The key here is of course that you press apply changes instead of doing incremental installs with the run with JRebel for Android button. For startups and incremental installs, you can expect the performance to be in the same ballpark than without JRebel for Android.
Also, you will see message “Desugar is nonincremental (slow) in Android Gradle Plugin 3.0.0” a lot, leading to longer build time, but issue already reported to Google issue tracker.
The main issue for me personally is annual license price, JRebel provides calculator where you can check is it worth it or not. In Android development build times usually are somehow smaller than in Java development, my largest project clean build takes 1 minute and 20 seconds on MacBook Pro i7. My builds can vary from day to day, but it is definitely not 10 times per hour. Sometimes when I change the layout and can’t see changes in the editor, I can rebuild many times, but on another day I could rebuild only once or twice only. Calculator promised me efficiency improvement from 2% to 7% for 475$ yearly.
Is it worth it? Decide for yourself, but keep in mind that you have many options how to improve your build times without JRebel or Instant Run by fine-tuning your gradle file, like disabling png cruncher, build debug builds for specific device and API with disabling ABI and multi-APK management, using latest Android Gradle plugin, avoiding legacy multidex etc..
I’m still using my JRebel trial version and maybe I’ll find out more pros and cons about it and share them here. I encourage you to try it yourself, maybe you could skyrocket those efficiency numbers and share your experience in comments.
Receive a new Mobile development related stories first. — Hit that follow button
Twitter: @ ChiliLabs