Speed Up Your Android Development with these 10 Libraries (Part 2)
SATURDAY DECEMBER 31 2016 - 8 MIN
In the first part of this post, we learnt about ButterKnife, SDP, Joda Time, ActiveAndroid and EventBus libraries to help us speed up our Android development. Now, let's continue from where we left off and explore the remaining libraries in our list.
Volley
Network operations have always been a frustrating task for developers mainly due to the excessive amount of tedious work involved. Without the help of any networking library, to read from even the most basic REST APIs that spits data in JSON
format, you will need to setup an HttpURLConnection
, InputStream
/OutputStream
, a JSON parser and you will also have to place all these tasks into an AsyncTask
to separate them from UI thread and run asynchronously. That's a lot of work with a lot of boilerplate code, probably more than anything else considering the work we are getting done for the amount of code that we write.
Volley is a HTTP networking library by Google that makes networking tasks easier, helps you get rid of boilerplate and most importantly, it's faster. Some of the key benefits of Volley are:
- Automatic scheduling of network requests.
- Multiple concurrent network connections.
- Support for request prioritization.
- Highly flexible and easily customizable.
- Comes with debugging and tracing tools.
However, Google advices not to use Volley for large download or streaming operations, since Volley holds all responses in memory during parsing. Another limitation is that the only response types supported are String
, Image
, JSONObject
, and JSONArray
also note that there is also no built-in XML
support, but due to Volley's flexibility you can build one yourself.
Setup
Setup for Volley is fairly simple, just add this line to your app/build.gradle file and you are good to go:
compile 'com.android.volley:volley:1.0.0'
Usage
Make sure you have android.permission.INTERNET
permission in your manifest file.
Create a RequestQueue
using Volley's convenience method Volley.newRequestQueue
:
RequestQueue queue = Volley.newRequestQueue(context);
Specify the URL for request you are making:
final String URL ="http://www.mywebservice.com";
Create a Volley Request.
There are plenty of available request types such as
StringRequest
,JsonObjectRequest
,JsonArrayRequest
as well as your custom defined request types.
StringRequest request = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// Display first 50 characters of the response string.
Toast.makeText(context, "Response is: "+
response.substring(0,50), Toast.LENGTH_LONG).show();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// In case of error
Toast.makeText(context, "Error in response!",
Toast.LENGTH_LONG).show();
}
});
Finally, add this request to your Queue:
queue.add(request);
Although this eliminates a lot of excessive work but still involves a fair amount of code and also it isn't very clean. Nonetheless, it gets the job done, it's robust and very useful for small to medium scale projects.
Okhttp
Volley is a fairly easy to use and a complete package which provides support ranging from basic String response to Image loading. However, there are some problems. Quoting this answer on Stackoverflow by CommonsWare:
it is an unsupported, "throw the code over the wall and do an I|O presentation on it" library.
which is to say that all it does is "getting the job done". Which comes at a price of not-so-good-looking code, lack of multipart requests and most of the load being put on the device memory.
OkHttp is a networking library developed by Square for sending and receiving HTTP-based network requests. It is built on top of the Okio library, which tries to be more efficient about reading and writing data than the standard Java I/O libraries by creating a shared memory pool. It also is the underlying library for Retrofit library that provides type safety for consuming REST-based APIs.
Make sure you also check out Retrofit which is another awesome library by Square which competes with Volley. It is a Type-safe HTTP client for Android and Java that turns your HTTP API into a Java interface.
Setup
Add this line to your app/build.gradle file:
compile 'com.squareup.okhttp3:okhttp:3.3.0'
Usage
Again, first step is to make sure you have android.permission.INTERNET
permission in your manifest file.
Specify the URL for request you are making:
final String URL ="http://www.mywebservice.com";
Instantiate an OkHttpClient
and create a Request
object:
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(URL).build();
To make a synchronous network call, use the Client
to create a Call
object and use the execute
method.
Response response = client.newCall(request).execute();
To make asynchronous calls, also create a Call
object but use the enqueue
method.
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// Do your exception handling here
e.printStackTrace();
}
@Override
public void onResponse(Call call, final Response response)
throws IOException {
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
} else {
String text = response.body().string();
// Display first 50 characters of the response string.
Toast.makeText(context, "Response is: "+
text.substring(0,50), Toast.LENGTH_LONG).show();
}
}
}
Parceler
Now, that we are done with networking, let's take a look at another headache - creating Parcelable
objects. Although creating Parcelable
s is faster than using Serializable
s, creating Parcelable
objects requires creating a lot of boilerplate code in defining data exactly in the sequence that should be serialized and deserialized.
Parceler helps you automate this task. Similar to Butterknife this library generates the necessary wrapper classes for you at compile time automatically, saving you the repetitive steps required for leveraging the performance benefits of Parcelables.
Setup
Using Gradle, add this block to build.gradle at the project-level, it allows code generation libraries like Butterknife and Parceler for annotation processing:
dependencies {
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
And then in your app/build.gradle file, add the following:
apply plugin: 'com.neenbedankt.android-apt'
...
dependencies {
compile 'org.parceler:parceler-api:1.1.1'
apt 'org.parceler:parceler:1.1.1'
}
Usage
By using Parceler you no longer have to implement the Parcelable
interface, the writeToParcel()
or createFromParcel()
or the public static final CREATOR
. You simply annotate a POJO with @Parcel
and Parceler does the rest.
@Parcel
public class User {
String name;
int age;
// Empty constructor required by the Parceler library
public User() {}
public User(int age, String name) {
this.age = age;
this.name = name;
}
public String getName() { return name; }
public int getAge() { return age; }
}
To generated Parcelable from POJO, use the Parcels utility class:
Parcelable wrapped = Parcels.wrap(new Example("John Doe", 22));
To create your POJO from generated Parcelable
User user = Parcels.unwrap(wrapped);
user.getName(); // John Doe
user.getAge(); // 22
There is an Android Studio Plug-in which makes it even easier to generate
Parcelable
s. We will be looking at it in a future post dedicated to Android Studio Plug-ins.
Android Annotations
Android Annotations is a framework that speeds up Android development by replacing most of the repetitive tasks and patterns with java annotations. It takes care of the plumbing, and lets you concentrate on what's really important. By simplifying your code, it facilitates its maintenance.
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 {
apt "org.androidannotations:androidannotations:4.2.0"
compile "org.androidannotations:androidannotations-api:4.2.0"
}
Usage
Following is an example of a simple MainActivity
when used without Android Annotations library and when used with it:
Before
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
TextView msgTextView = (TextView) findViewById(R.id.tv_msg);
Button hideButton = (Button) findViewById(R.id.btn_hide);
hideButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
msgTextView.setVisibility(View.INVISIBLE);
}
});
}
}
After
@Fullscreen
@EActivity(R.layout.activity_main)
@WindowFeature(Window.FEATURE_NO_TITLE)
public class MainActivity extends AppCompatActivity {
@ViewById(R.id.tv_msg)
TextView mMsgTextView;
@Click(R.id.btn_hide)
protected void onHideButtonClick() {
mMsgTextView.setVisibility(View.INVISIBLE);
}
}
You can see how clean, concise and readable the code has become after using annotations. There's a lot more to this brilliant library, head over to official documentation to find out more features.
Espresso
So far we have covered different aspects of our development routine and tried to simplify them with the use of 3rd party libraries. This seems to increase overall performance and productivity in our projects but in the end if you cannot test it, it's probably not worth it. Testing has been an integral part of Software Engineering and Android development is no different. In your early days of Android development, you might be testing your applications manually by test driving them every time you added or fixed something. Many might still be doing the same if you have not switched to automated tools yet.
Espresso is part of Android Testing Support Library provided by Google. The basic idea is to get rid of manual testing and let the system do the UI testing for you in matter of seconds. You write intuitive and easy to read tests in the form of each individual action you have to perform in order to get the task done and then finally evaluate the results. All the operations in Espresso follow this simple pattern
Find A View ➜ Perform Some Action(s) ➜ Validate Output
Each of the steps in your test path are more or less exactly written step by step in Espresso and even a person with little or no knowledge about the domain or your project can easily start writing tests for your application. This ease of use makes it one of the best (if not the best) UI testing framework available for Android.
Setup
In the build.gradle file of your Android app module, you must set a dependency reference to the Espresso library:
androidTestCompile
'com.android.support.test.espresso:espresso-core:2.2.2'
Usage
If you are to test the Login screen of your application, you might have to first input email and password in the corresponding fields and then click the Sign In/Log In button. These are 3 separate operations, additionally you might want to first check if Login Form itself is visible. Finally you will check if the application displays a dialog indicating login success in case of successful Login. Let's see how to do this using Espresso.
@RunWith(AndroidJUnit4.class)
public class LoginActivityTest {
@Test
public void onLoginSuccess_displaysLoginSuccessDialog() {
//Declare our email and password
String username = "myusername@gmail.com";
String password = "mypassword";
// Login success dialog's message
String successMsg = "Login Successful";
// Check if Login form is visible
onView(withId(R.id.LLLogin)).check(matches(isDisplayed()));
// Fill details in form
onView(withId(R.id.ETUsername)).perform(typeText(username));
onView(withId(R.id.ETPassword)).perform(typeText(password));
// Click on Login button
onView(withId(R.id.BTLogin)).perform(click());
// Check if Login Success dialog is displayed
onView(withText(successMsg)).check(matches(isDisplayed()));
}
}
As you can see, this is just an easy to read and easy to write code representation of a real user's actions. You can create all sorts of complex tests by chaining these simple methods together. There are many different types of actions
, matchers
and other utilities available in Espresso API, to learn more about them, head over to the official Espresso Documentation.
Conclusion
So these were the ten must have libraries in my opinion that every Android developer must start using in order to make their code:
- Easy to write
- Easy to test
- Easy to maintain
- Concise and Performant
- Highly cohesive and low coupled
and finally improving your overall development speed and productivity, because in the end being a good developer is about working smart, not hard. I hope you have found this article useful. Feel free to provide your valuable feedback.
Most of the example code and definitions were adopted from official sources to avoid any errors.