Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Getting Started With JRebel for Android

DZone's Guide to

Getting Started With JRebel for Android

A tutorial on how to use JRebel to squeeze the most out of your Gradle builds for Android apps.

· Mobile Zone
Free Resource

Download this comprehensive Mobile Testing Reference Guide to help prioritize which mobile devices and OSs to test against, brought to you in partnership with Sauce Labs.

Introduction 

Android development is great as long as your project stays relatively small. As the functionality of your project grows you’ll find that your build times follow suit. This puts you in the position where you spend most of your time figuring how to make your build run faster rather than adding more value to your actual app.

The interwebs are packed full with suggestions of how to squeeze the most out of your Gradle builds. There are some great posts on this, including, “Making Gradle builds faster”. Although you can win back seconds and maybe even minutes, some bottlenecks will still remain in your build. For example, having annotation-based dependency injections are nice to have for a cleaner architecture, but it has an impact on your build time.

One thing you can try is JRebel for Android. It takes a different approach by not introducing a new apk after each change. Instead, the APK gets installed once and delta packages are shipped over to the device or emulator and are applied during runtime. This logic is nothing new and has been present in the Java EE/SE and JRebel for more than 8 years.

Let’s take the Google IO 2015 app and see how the JRebel for Android setup works as well as how it can save you valuable time.

Installing JRebel for Android

JRebel for Android is available as a plugin for Android Studio. You can download it directly from the IDE by navigating to Plugins > Browse Repositories and searching for “JRebel for Android”.

Image title

If for some reason you can’t access the public maven repositories you can download it directly from the JetBrains homepage. After which you need to install via the Plugins > Install plugin from disk… route.

Once the plugin is installed, you’ll need to restart Android Studio, as usual after a plugin installation. After restart, you need to provide your name and email to get your free 21 day trial of JRebel for Android.

Running My Application With JRebel for Android

Now the plugin is installed, you just need to click the Run with JRebel for Android button, which will always build a new apk if changes are detected between the previous installation. Run with JRebel for Android is the same as the Run action in Android Studio. So you’ll be faced with the same run flow, where you first need to pick a device and then apk is built and installed on that device etc.

To update your code and resources, JRebel for Android needs to process the project’s classes and embed an agent to the application. JRebel for Android will only run with a debuggable flavor, so your release apk is never affected. In addition no changes are required to your project. For a detailed overview of how JRebel for Android works, read this under the hood post.

So pressing Run with JRebel for Android on the Google IO 2015 application would result in the following:

Image title

Applying Changes With JRebel for Android

The Apply changes button is the key when using JRebel for Android, it will do the least amount of work possible to make your changes and updates visible on your device. If you didn’t use Run with JRebel for Android to install the application yet, Apply changes will take care of the installation on your behalf.

Now let’s make a simple functional change to the application. For each session taking place in GoogleIO you can send feedback. We’ll add one additional element to the question, an input for your name and we’ll use the value from that input in a Toast thanking you for providing feedback.

Step 1: Add an EditText component to the session_feedback_fragment.xml

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <EditText
        android:id="@+id/name_input"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</FrameLayout>

Image title

Step 2: Fix the paddings

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="@dimen/padding_normal"
    android:paddingStart="@dimen/padding_normal"
    android:paddingRight="@dimen/padding_normal"
    android:paddingEnd="@dimen/padding_normal"
    android:paddingTop="@dimen/spacing_micro"
    android:paddingBottom="@dimen/padding_normal">

Image title

Step 3: Add a hint

<EditText
    android:id="@+id/name_input"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="@string/name_hint"/>

Image title

During all of these changes we have remained on the same screen on our device throughout. After each Apply change Activity.recreate() is invoked by JRebel for Android. So your topmost activity will go through the same callbacks as you would if you rotated your device from portrait to landscape, for example.

So far we’ve only performed resource changes, so let’s change some Java code as well.

Step 4: Show a toast in SessionFeedbackFragment.sumbitFeedback()

EditText nameInput = (EditText) getView().findViewById(R.id.name_input);
Toast.makeText(getActivity(), "Thanks for the feedback " + nameInput.getEditableText().toString(), Toast.LENGTH_SHORT).show();

Image title

If reading isn't believing, here is a short JRebel for Android in action video:


Application Restart vs. Activity Restart

Not all changes will trigger an Activity.recreate() invocation. Should you change something in the AndroidManifest, a new APK has to be built and an incremental install will be performed. In this case the application will be restarted. An application restart will also be done if you replace a superclass or change interfaces that the class is implementing. Here is a full breakdown of activity vs. application restart:

Activity restart Application restart

Adding, removing, modifying methods

Adding, removing implemented interfaces

Adding, removing, modifying constructors

Replacing superclasses

Adding, removing fields

Adding, removing classes

Adding, removing annotations

Adding, removing, modifying static fields value

Adding, removing enum values

Modifying interface

Adding, removing, modifying XML resources

Analysts agree that a mix of emulators/simulators and real devices are necessary to optimize your mobile app testing - learn more in this white paper, brought to you in partnership with Sauce Labs.

Topics:
android ,android development ,android studio ,gradle

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}