Loading...
Home
  • Tech Blogs
  • Videos
  • Conferences
    • Droidcon News
    • Upcoming Conferences
    • Become a Partner
    • Past Events
    • Keep Me Informed
    • Diversity Scholarships
  • Community
    • droidcon Team
    • How to Hold a Droidcon
  • Android Careers
Sign In

Global CSS

 

Build a Simple Networking Library in Android (Part 1)

 

 
Ashish Yadov
Android App and Library dev.
Published: February 01, 2021
Tweet
Share
 

 

The idea of library internals has always been intimidating to me. Most people being an app developer prefer to assume the library as a black box. How do people code it, test it or release it? You are in for a treat as in my series of articles I will take you on a journey of creating, running and publishing an actual working library. Yes, we won’t be doing some “Hello World” stuff. We will create a real Android Library through which can make API requests and get the result. It will be 2 part series:

  1. All about the creation of the networking module
  2. Locally publish our library and run in demo/test app, check here

 

 

A little sneak peek to get you excited!

We will try to accomplish a very Simple Networking Library. It will make real network calls from API and give a response in JSONObject. Our library will model a network request by taking a URL, Method, Header, Body and return response via an interface.
Want to have a sneak peek of a simple GET request on a mock API? Below is a code snippet that the library will expose:

 

 

Creation of networking module

To begin with, we will create a new module that will contain all the library internals. Our module will comprise all the code necessary for making the network request, parsing the response, thread management and last but not least, returning response via an interface. Let’s head over to the starting point!

 

The Starting point

In the current Android Studio, it’s straightforward to get started for library development. Just a few clicks, no manual editing in any file.

Go to: File > New > New Module > Android Library. You will get something like this:

 

Image for post

 

Create New Module has five options:

  1. Module name: name of your library (I have named it simple-networking)
  2. Package name: unique name to differentiate with other libraries
  3. Language: We are going to focus on Kotlin
  4. Bytecode Level: 8 means Java 8 (if you want Java 7 you change from the drop-down)
  5. Minimum SDK: Minimum Android API level for this SDK to compile.

Caution: The project which will be using our library it’s API level ≥ Libray API level. So choose the version carefully. For simplicity, I have kept the API level as 21 (94% device support)

Now hit Finish, the module is ready (after Gradle sync and indexing). Now we can talk about the architecture of the library module.

 

The Architecture

The libraries lack fixed structure defined as compared to app development. It depends on what you want to build and then have an architecture. We are building a Simple Networking library. It is supposed to make a network request, then parse the raw response and give a useful result back via an interface. For someone who is integrating our library should be able to configure fields like URL, HTTP Methods, Message Body, Request Headers. Here are the requirements for what we are building:

  1. Request Builder: A Builder class to set URL, method, body, header. It also has a ThreadExecutor to execute the request on bg thread. And lastly, a JSONObjectListener to listen for API response in JSON.
  2. RequestTask: Takes the Request Builder as a parameter to make the connection request and parse the response. It will give the acknowledgement back in a Response class as JSONObject.

We will try to put Request, RequestTask & Response in a single class named Http. Now that we have decided the necessary things for architecture. Let’s code the above two, starting with Request Builder.

 

1. Request Builder

This class will be responsible for creating the network Request. It will be a Builder class which will take the HTTP method in constructor. Supported methods will be GET, POST, DELETE, PUT. The other configurable parameters will be URL, Request Header and Request Body

Other configurable parameters will be URL, Request Header and MessageBody:

  1. URL: It stands for Uniform Resource Locator. A URL is nothing more than the address of a given unique resource on the Web. The builder for URL will look like this:

 

 
 

The var url is internal as we already exposed the function get the URL. Firstly we will assign the received url to our class member then we will return this to follow Builder pattern. Check here, for learning about Builder pattern.

 

2. Request Header: According to Mozilla, HTTP headers let the client and the server pass additional information with an HTTP request or response. You can read more about headers here. By default, there are always some headers, but we can enable the functionality to add custom headers (if any). The builder for the header will look this:

 

 

The var header is internal as we already exposed the method get the header. We have added support to only allow header as a map (key-value pair). So we need to check whether it has any key-value pair, i.e. by isNullOrEmpty(). And then if all good we will put all the data from the received map in the class member’s map

 

3. Message Body: The message body part is optional for an HTTP message. It carries the entity-body associated with the request or response. You can read more about headers here. The builder for the body looks like this:

 

 

The var body is internal as we already exposed the method get the body. We have kept body as ByteArray as the HttpURLConnection supports only ByteArray as a type for body. But to make it easier for integration, we have to expose the body() function with JSONObject. Internally we are converting the JSON to String and then the String to a byte array. And then store it in the class member named body. Also, we have added Content-Type as application/json in the header as our body type is JSON. It is necessary as The MIME media type for JSON text is application/json

 

We have two more methods to support our Request class to make the connection request and send the response back. Before this, we need two more things, a ThreadExecutor (for creating a background thread) and JSONObjectListener (interface to give back the API response).

ThreadExecutor: Creates and executes thread for the connection request on the background thread.

 

 

execute() method takes a runnable and creates a HandlerThread by assigning the priority. To make it easier, we have used Process.THREAD_PRIORITY_DEFAULT, read more about it here. After making the thread (via handlerThread) we will create the handler object. Lastly, post the runnable via the handler.

 

Why not coroutines in place of HandlerThread?

We will have to integrate the coroutine library. Then our library will be bloated, which is not a good practice.

JSONObjectListener: This interface will give a response or failure from the API.

 

 

The response will be org.json.JSONObject and failure will be java.lang.Exception

 

Now we can bring back our focus on two more remaining methods to support our Request class, to make the connection request and send the response back:

  1. makeRequest(): makes the connection request for the existing builder, the Request object.

 

 

jsonObjReqListener is assigned to a class member here. This method takes an interface as an argument which will give the response back to the user. ThreadExecutor is used to pass this (current Request) in RequestTask which is a Runnable class as the ThreadExecutor’s execute() will take only Runnable (can be checked above). RequestTask, discussed in detail below.

 

2. sendResponse(): An internal method to invoke the response interface.

 

 

The above also takes a Response object (used to store the JSON response), the Response class is in detail below. It also takes care of failed requests. If the Exception(e) is not null then it is an exception else a success response comprising JSONObject.

 

Now we are done with the Request part. It contains everything required to make an API request. Check here to get the full overview of Request class. Now we will focus on how we can use the Request inside RequestTask.

 

2. Request Task

This class takes the above class i.e. Request as a constructor parameter. This class implements Runnable class so the main thread is not blocked. This class is Runnable as our current ThreadExecutor takes only Runnable class as a parameter. The signature of our class is as follows:

 

internal class RequestTask(private val req: Request) : Runnable {}

 

It is kept internal as we don’t want to expose it as it is not needed for someone who is integrating our library. RequestTask has three methods:

  1. run(): as the class implements runnable so this method will be overridden.

 

 
 

The run method creates a object of HttpURLConnection by calling getHttpURLConn(). The connection is then passed to parseResponse(). The req is actually Request class obj (passed in the constructor) which is used to access the sendResponse() method, in turn give the response back. The above also handles the exception scenario and sends back the apt response.

2. request(): Creates an object of HttpURLConnection. This method is the most core part of our library as it makes the connection writes the response as a stream.

 

 

Creates the obj by taking the req i.e. Request (passed in the constructor). It takes the URL and then opens the connection. Then takes the method (i.e. GET, POST, PUT, DELETE). Also iterates through the request header map, and writes the request body in the connection stream. In a nutshell, whatever we have used in the Builder class Request will be used here to make the connection. Lastly, makes the connection by calling connect().

 

3. parseResponse(): Parses the response received from the network call. Basically, the network gives back the response in ByteArrayOutputStream. The below method converts it into a useful/readable Response.

 

 

The above method checks for the valid status code. We are considering 2xx as success. After this, we get the InputStream, also taking care of the invalid status by reading the error response. Now the InputStream can be written to ByteArray and gives it to Response class (discussed below). It also disconnects after done with the request. Take a look at the full RequestTask here.

 

Response class: It converts the ByteArray response to JSONObject and stores it.

 

 

The ByteArray response gets converted to a String by encoding it as UTF-8. And then a JSONObject is created from the String. We can argue that we could have parsed directly to JSONObject. Response as a separate class allows us to extend functionality (in future maybe JSONArray) & keep things separated.

 

3. Assembling Request, RequestTask and Response

If you remember the sneak peek into a code I had mentioned in a section above. I had some Http.Request something? That’s why we will now assemble Request, RequestTask & Response in a single class. I have named it Http.kt, take a look at the same here. It’s a fairly large class so it’s not posted below and you can easily check on Github gist. I have kept it as object class because Kotlin provides an easy way to create singletons using the object declaration feature.

 

 

We are done with the core part of our library module (simple-networking). But at this stage, this library can’t be used in any project. In order to get there, we need to publish our library. Check out part 2 to learn this.

 

 

 

Tags: Sdk, Android, Android Sdk, Library Design, Android Libraries

 

View original article at: 


 

Originally published: January 14, 2021

Android News
Compose CameraX on Android
Compose CameraX on Android

By Peng Jiang

Android new UI toolkit Jetpack compose is in beta now, which has all the features you need to build production-ready apps. CameraX is another Jetpack support library, which let you control the camera easier. As compose is still under development, lots of the views are still not available the compose way.

By ProAndroidDev -
Android News
Getting… your BottomSheetScaffold working on Jetpack Compose Beta 03
Getting… your BottomSheetScaffold working on Jetpack Compose Beta 03

By Carlos Mota

It’s Monday, no releases this week, and… there’s a new version of Jetpack Compose — beta 03—available. What a perfect time to just increment 02 to 03 and see what’s new. The API is (almost) final so after updating from alpha to beta there weren’t any big changes to do. However, and remember that’s still in development, there’s always something that I need to update. 

By ProAndroidDev -
Android News
Noisy Code With Kotlin Scopes
Noisy Code With Kotlin Scopes

By Chetan Gupta

Scopes make your code more readable? think again... You are going to encounter these scope functions namely let, run, apply, also, within every Kotlin codebase, along with all the mischievous ways developers exploit their usage from the way they were intended for. Let see how popular opinion on those ends up just as a code noise.

By ProAndroidDev -
Android News
Improving Android DataBinding with Bindables library
Improving Android DataBinding with Bindables library

By Jaewoong Eum

DataBinding is one of the most important factors for MVVM architecture. The basic concept of DataBinding is to link the view and view model via observer patterns, properties, event callbacks, etc. Linking and automating communication between the view via the bound properties or something in the view model has a lot of benefits in the MVVM architecture concept.

By ProAndroidDev -
droidcon News

Tech Showcases,

Developer Resources &

Partners

/portal/rest/jcr/repository/collaboration/Groups/spaces/droidcon_hq/Documents/public/home-details/EmployerBrandingHeader
EmployerBrandingHeader
https://jobs.droidcon.com/
/portal/rest/jcr/repository/collaboration/Groups/spaces/droidcon_hq/Documents/public/employerbranding/jobs-droidcon/jobs.droidcon.com
jobs.droidcon.com

Latest Android Jobs

http://www.kotlinweekly.net/
/portal/rest/jcr/repository/collaboration/Groups/spaces/droidcon_hq/Documents/public/employerbranding/kotlin-weekly/Kotlin Weekly
Kotlin Weekly

Your weekly dose of Kotlin

https://proandroiddev.com/
/portal/rest/jcr/repository/collaboration/Groups/spaces/droidcon_hq/Documents/public/employerbranding/pad/ProAndroidDev
ProAndroidDev

Android Tech Blogs, Case Studies and Step-by-Step Coding

/detail?content-id=/repository/collaboration/Groups/spaces/droidcon_hq/Documents/public/employerbranding/Zalando/Zalando
/portal/rest/jcr/repository/collaboration/Groups/spaces/droidcon_hq/Documents/public/employerbranding/Zalando/Zalando
Zalando

Meet one of Berlin's top employers

/detail?content-id=/repository/collaboration/Groups/spaces/droidcon_hq/Documents/public/employerbranding/Academy for App Success/Academy for App Success
/portal/rest/jcr/repository/collaboration/Groups/spaces/droidcon_hq/Documents/public/employerbranding/Academy for App Success/Academy for App Success
Academy for App Success

Google Play resources tailored for the global droidcon community

Follow us

Team droidcon

Get in touch with us

Write us an Email

 

 

Quicklinks

> Code of Conduct

> Terms and Conditions

> How to hold a conference

> FAQs

> Imprint

Droidcon is a registered trademark of Mobile Seasons GmbH Copyright © 2020. All rights reserved.

powered by Breakpoint One