Indispensable Android Libraries

With recent surge in adoption of the new Gradle-based Android build system, it’s easier than ever to incorporate Android library projects (and libraries in general) into your project. Gone are the days of complex pom files, submodules, forked repos, a huge libs folder or worst of all, copying code as-is into your repo (you never did that, right?). Now a full Android library or utility can be included with a one-line addition to your build.gradle file. Here are a few that I find extremely useful in my day to day work.

Dagger

compile 'com.squareup.dagger:dagger:1.2.1'
compile 'com.squareup.dagger:dagger-compiler:1.2.1'

I’ve praised Dagger (brought to you by the guys at Square, Inc.) and dependency injection in general previously, but it deserves the first spot on this list because it is usually the first thing I add to a project. I’ve tried to avoid using it for fear that I have blinders on, but end up pulling it in after I dive into constructor hell or static methods that pass Contexts all over the place. It just feels cleaner to be able to, where appropriate, inject and not have to worry about how every class is constructed. This is especially true when trying to maintain common library projects that my apps depend on. With Dagger, I can change dependencies without needing to refactor all of my app code. There is a bit of a learning curve if you’re not familiar with dependency injection or are used to the “magic” behind other DI frameworks like Guice, but it is a very powerful tool to have in your Android toolbox.

ButterKnife

compile 'com.jakewharton:butterknife:4.0.1@jar'

Jake Wharton, a Square engineer, created this library to answer all of the “why doesn’t Dagger support view injection” questions they were getting. That said, this surprising optimization makes for much cleaner Activities / Fragments. It may not sound like much but it does away with the need for findViewById calls and casting for every view you need to do something with.

@InjectView(R.id.textView)
TextView textView;
 
@Override public void onCreateView(Inflater inflater, ViewGroup containter, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_my_layout, container, false);
    ButterKnife.inject(this, rootView);
    // all @InjectView annotated fields based on the id passed in as the arg.
    return rootView;
}

Cupboard

compile 'nl.qbusict:cupboard:1.0.5'

Cupboard (by Hugo Visser at Qbus) is an ORM, kind of. It helps persist simple POJOs to disk, but in doing so, can save you a ton of dev time. What used to be a bunch of static SQL strings in a SQLiteOpenHelper or cursor management in an adapter can now be folded up into a few calls to the Cupboard library. It makes it dead simple to build a database with a sane schema to represent simple POJOs and query them with all of the power of raw SQL (which, due to its lightweight nature, you still need to do a bit of on occasion and that’s a good thing).

Read Cupboard’s wiki to get the fine details of installation / integration then add, query and remove with a line or two of code.

Entry e = cupboard().withDatabase(db).get(Entry.class, id); // get by id
entry.setTitle("Different Title"); // modify the object
cupboard().withDatabase(db).put(entry); // update
Iterable entries = cupboard().withDatabase(db).query(Entry.class).withSelection("title = ?", "Different Title").query();

It gets really fun and powerful when you make your model classes Parcelable for easily passing around various Android components.

Parceler

compile 'org.parceler:parceler:0.2.6'
compile 'org.parceler:parceler-api:0.2.6'

Speaking of Parcelables. Parceler by John Ericksen removes the boilerplate from Parcelables. An annotation is all that is needed (in most cases) to make a type parcelable:

@Parcel public class MyEntry {
    public String title;
    public MyEntry();
    public MyEntry(String title){/*...*/}
}

The docs cover how to pack this and unpack this into bundles and the like via static method calls, but that’s pretty much it.

Picasso

compile 'com.squareup.picasso:picasso:2.1.1@jar'

Picasso is the 3rd utility on this list created by the engineers at Square. They seem to produce nothing but useful and open-sourced tools. This is yet another that takes a task that is surprisingly difficult and turns it into a line of code. Managing the loading of Bitmaps into views on Android seems simple at the surface but doing it right involves carefully balancing disk and memory caches, the use of background and the UI thread, all the while dealing with the potential for IO issues. Picasso handles most of this for you. As an example:

Picasso.with(context).load(url).placeholder(R.drawable.placeholder).error(R.drawable.ruhRoh).centerCrop().into(imageView);

That’s it. All of that complexity, hidden behind a line (ok, a line-ish) of code. There’s more to it as well. If you plan on having any interesting or dynamically loaded images in your app, you owe yourself a try at Picasso.

Tape

compile 'com.squareup:tape:1.1.0@jar'

While ¬†you owe it to yourself to try everything else on this list, you owe it to your users to try Tape. Tape is an easy and reliable way to persist objects to a fifo-queue on disk. It’s perfect for a network request queue. It’s amazing how frequently requests fail in the wild. Don’t leave you users hanging by dropping those failed requests in memory. First write them to a queue on disk in you lose that wifi lock you requested. Kick off a service to peek the queue and execute the request. Remove only on success. You just saved yourselves a bunch of 1-star reviews when your users didn’t lose the content they spent so much time producing in your app. See the Tape website for examples and setup; it’s more than a one or two liner, but completely worth the effort. Also worth mentioning that Square is behind this one as well.

Android Support Libraries

compile 'com.android.support:support-v4:+'
compile 'com.android.support:appcompat-v7:+'

This is obvious but worth pointing out. The support libraries are truly indispensable, especially with recent updates. They’re now available without referencing your SDK folder or copying the jars into a libs folder. A quick setup via the SDK manager of the repo allows them to be included like the other dependencies listed here. They’re also at the point now that you can build apps with fully functioning action bars, fragments and other HoneyComb+ niceties going all the way back to Gingerbread.