Zuhaib

Speed Up Your Android Development with these 10 Libraries (Part 1)

SATURDAY DECEMBER 17 2016 - 7 MIN

Introduction

An average developer writes somewhere between few dozen to a couple of hundred lines of code per day. If you are an Android developer, you might be closer to the upper limit. Reason? Boilerplate.. A LOT OF BOILERPLATE!

From findViewById() to writing Adapters and Interfaces for different types of operation, we write loads of boilerplate everyday (at least we juniors do!). Some people still seems surprised about the "10 Lines per Developer per Day" statement from The Mythical Man-Month (a must read book for any software engineer) and some even proudly say that they could beat it by huge margin (impressive!!). What many seems to neglect is the importance of negative code count. You gain more advantage by removing (refactoring) code than by adding new.

If we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent". - Edsger Dijkstra

Now if you apply this theory to Android development, this makes a big difference. What if you were able to remove even half of the boilerplate code from your projects? You might be able to achieve 2x development speed to say the least.

Android community is enormous and they keep improving the eco-system with latest libraries and methodologies. There are actually plenty of libraries already written to boost the development speed. In this post, we will discuss my list of 10 must have libraries that can boost your Android development.



ButterKnife

findViewById()
setOnClickListener(this)

How many times do you have to write this code in a single project? A year ago, a single Activity (with a complex UI) in one of my projects had about 150 lines of only this code (along with some default value settings). Out of embarrassment, I decided to move this code out from onCreate method to into its own method setComponents() and hide it somewhere near the end of the class. Why? to make it look.. well.. less embarrassing *cough*

Few months back, I got to work on that project again. First of all, I took a fair share of time to laugh at that mess. I ended up replacing most of the UI related boilerplate with ButterKnife and the code count of that particular Activity came down to somewhere around 900 from 1700+. Image what affect this small changed made to the entire project.

Butterknife is a View Injection library that uses annotations to automatically generate common boilerplate code and that too in its own auto-generated classes. This not only saves you a lot of time but also makes your code cleaner and concise.

Setup

Using Gradle, add this block to build.gradle at the project-level:

buildscript { repositories { mavenCentral() } dependencies { classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' } }

And then in your app/build.gradle file, add the following:

apply plugin: 'android-apt' ... dependencies { compile 'com.jakewharton:butterknife:8.4.0' apt 'com.jakewharton:butterknife-compiler:8.4.0' }

Usage

Eliminate findViewById with @BindView on field declaration:

class ExampleActivity extends Activity { // Automatically finds each field by the specified ID. @BindView(R.id.title) TextView title; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.simple_activity); ButterKnife.bind(this); // Start using your fields... } }

Improved Listeners with annotations:

@OnClick(R.id.submit) public void sayHi(Button button) { button.setText("Hello!"); }

You can even eliminate resource lookups with resource annotations:

class ExampleActivity extends Activity { @BindString(R.string.title) String title; @BindDrawable(R.drawable.graphic) Drawable graphic; @BindColor(R.color.red) int red; @BindDimen(R.dimen.spacer) Float spacer; // ... }

This is just the tip of an iceberg, there is a lot more to this library. To learn more, head over to the library's page on creator @JakeWharton 's website.

BONUS: There is even an Android Studio plug-in for Butterknife called ButterKnifeZelezny, it automates the binding process with a few clicks, making things lightning fast!

SDP

No # 2 on my list is a real underdog but a true life-saver! Even if you have only written a basic Hello World program so far. You might be well aware of the problems with supporting vast variety of screen sizes associated with Android devices. No matter how many variations you create for your layout, there will always be some devices that will completely destroy your layout.

SDP resolves this problem to some extent by providing a new size unit named sdp (scalable dp). This size unit scales with the screen size hence leading to adaptive layouts. Although this approach is not entirely foolproof and most experienced developers might insist on avoiding it, still I found it very helpful and reliable so far.

Setup

Add the following dependency in your app/build.gradle file:

dependencies { compile 'com.intuit.sdp:sdp-android:1.0.4' }

Usage

Not much changes with this library. You only need to develop one layout variation for phones and one for tablets (yes, just two!). The process is exactly the same as your normal layout file, the only difference is that you replace dp with sdp resource values provided by the library in your layout.

<View android:layout_width="@dimen/\_24sdp" android:layout_height="wrap_content" ... />

To learn more about usage and sample layout, go the project's GitHub repository.

Joda Time

Almost every project require some level of date and time manipulation. The standard date and time classes prior to Java SE 8 are poorly written and broken to some extent. Joda-Time became the de facto standard date and time library for Java due to its extra ordinary capabilities. The design allows for multiple calendar systems (such as Gregorian, Julian, Buddhist, Coptic, Ethiopic and Islamic calendar systems), while still providing a simple API. There is a lot more to it which you can find out at project's GitHub repository.

Setup

Add the following dependency in your app/build.gradle file:

dependencies { compile 'joda-time:joda-time:2.9.6' }

Usage

public boolean isAfterPayDay(DateTime datetime) { if (datetime.getMonthOfYear() == 2) { // February is month 2!! return datetime.getDayOfMonth() > 26; } return datetime.getDayOfMonth() > 28; } public Days daysToNewYear(LocalDate fromDate) { LocalDate newYear = fromDate.plusYears(1).withDayOfYear(1); return Days.daysBetween(fromDate, newYear); } public boolean isRentalOverdue(DateTime datetimeRented) { Period rentalPeriod = new Period().withDays(2).withHours(12); return datetimeRented.plus(rentalPeriod).isBeforeNow(); } public String getBirthMonthText(LocalDate dateOfBirth) { return dateOfBirth.monthOfYear().getAsText(Locale.ENGLISH); }

ActiveAndroid

One of the most painful tasks in Android development is setting up an SQLite Database. With all the Keys, Tables, Cursors, Helper and what not, it usually takes an entire package full of classes (filled with boilerplate code for the most part) to be able to produce even the most simplest Databases. ActiveAndroid takes care of all the setup and messy stuff, and all with just a few simple steps of configuration.

So what exactly is ActiveAndroid?

ActiveAndroid is an active record style ORM (object relational mapper). Which allows you to save and retrieve SQLite database records without ever writing a single SQL statement. Each database record is wrapped neatly into a class with methods like save() and delete().

Setup

Add the following dependency in your app/build.gradle file:

repositories { mavenCentral() maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } } compile 'com.michaelpardo:activeandroid:3.1.0-SNAPSHOT'

Next, configure your project by adding some global settings in your AndroidManifest.xml file:

<manifest ...> <application android:name="com.activeandroid.app.Application" ...> ... <!--Database name--> <meta-data android:name="AA_DB_NAME" android:value="Pickrand.db" /> <!--Database version (default should be 1)--> <meta-data android:name="AA_DB_VERSION" android:value="5" /> </application> </manifest>

Notice also that the application name points to the ActiveAndroid application class. If you are using a custom Application class, just extend com.activeandroid.app.Application instead of android.app.Application.

Even if you are already extending Application class from another library, you can initialize ActiveAndroid in its onCreate method:

public class MyApplication extends SomeLibraryApplication { @Override public void onCreate() { super.onCreate(); ActiveAndroid.initialize(this); } }

ActiveAndroid is a very powerful library, and thus its setup process takes a bit longer than others we have seen so far. You might run into few issues in your first attempt as well. For troubleshooting and guides, go to the official documentation.

Usage

Usage of ActiveAndroid is a very broad topic and even a post dedicated to it will not be sufficient to cover all the features. So we leave this to the official wiki where you can learn almost everything about it.

EventBus

You might be used to writing Interfaces for communication between your Activities and Fragments as well as different modules of your project. Now this is a pretty standard way of doing things but as your projects starts to grow, things may get out of hands. As a result, developers often end up with tightly coupling the components of their Application. This results in a code that is less maintainable and hard to test.

EventBus is a popular open-source library that was created to solve this problem using the publisher/subscriber pattern.

EventBus enables central communication to decoupled classes with just a few lines of code resulting in simplification of code, low coupling, high cohesion, and ultimately speeding up your development.

Setup

Add the following dependency in your app/build.gradle file:

compile 'org.greenrobot:eventbus:3.0.0'

Usage

Define events: Events are POJO (plain old Java object) without any specific requirements.

public class LoginEvent { public final boolean status; public LoginEvent(boolean status) { this.status = status; } public boolean getStatus(){ return status; } }

Prepare subscribers: Subscribers implement event handling methods that will be called when an event is posted. These are defined with the @Subscribe annotation.

// This method will be called when a LoginEvent is posted @Subscribe public void handleLoginEvent(LoginEvent event) { boolean status = event.getStatus(); if(status) // Show welcome message if status is true showWelcomeMessage(); else // Otherwise show login fail message showLoginFailedMessage(); }

Subscribers also need to register themselves to and unregister from the bus.

@Override public void onStart() { super.onStart(); // Register subscribers on activity start EventBus.getDefault().register(this); } @Override public void onStop() { // Unregister subscribers on activity stop EventBus.getDefault().unregister(this); super.onStop(); }

Post Events: Post an event from any part of your code. All currently registered subscribers matching the event type will receive it.

EventBus.getDefault().post(new LoginEvent(isLogin));

These were the first five from the list of libraries to help us speed up our Android development. Find out about the remaining five in the second part of this post.


Most of the example code and definitions were adopted from official sources to avoid any errors.

Zuhaib Ahmad © 2023