Getting Started With Debugging in Android Using Chucker
Working with OkHttp
to perform network calls is always easy. The problem arises when you want to debug and see whether the task is successful or not.
<!--more-->
Chucker comes in handy when debugging using the OkHttp
library. Chucker is a simple to integrate android debugging library unlike Timber and Stetho.
You might be wondering what debugging is in Android development. Debugging is defined as the process of analyzing the code in software to detect and remove potential errors that might cause your app to crash.
Table of contents
- Table of contents
- Prerequisites
- What is Chucker
- What is OkHttp
- Getting started
- Adding dependencies
- Features of Chucker library
- Configuring Chucker
- Conclusion
Prerequisites
To follow through this tutorial, you must have:
- Android Studio IDE installed.
- Kotlin programming language basics.
- Kotlin coroutines basics.
What is Chucker
Chucker is an open-source Android debugging library produced and maintained by the Chucker team. The library is used to handle HTTP(S) inspections fired from an Android device. It works as an OkHttp interceptor
by providing a user interface for inspecting and sharing the OkHttp events inside your application.
When you integrate your app with Chucker, it will display a push notification displaying a summary of HTTP activities that are in progress. Take a look at the example below:
When you click on the push notification, a complete Chucker UI is launched from where you can inspect the network response.
The push notification can still be prevented from showing allowing Chucker UI to be launched directly from its interface. This is because when installing/building your app in Android Studio, Chucker 'app' is installed alongside yours.
What is OkHttp
OkHttp is built on top of HTTP. We can define HTTP as the protocol that governs how modern applications communicate over a network. It can either be via a secured channel (HTTPS) or an unsecured channel (HTTP).
OkHttp can be defined as an open-source library used to send and receive HTTP-based network requests efficiently. For further reading on OkHttp, please refer here.
Getting started
To get started with Chucker, open your Android Studio and create a new project. In this case, we will use a project with a simple UI having a TextView
for displaying the response from the internet.
Adding dependencies
In your app-level build.gradle
file, add the following dependencies:
// Chucker
debugImplementation "com.github.chuckerteam.chucker:library:3.5.2"
releaseImplementation "com.github.chuckerteam.chucker:library-no-op:3.5.2"
// OkHttp BOM
implementation(platform("com.squareup.okhttp3:okhttp-bom:4.9.3"))
// OkHttp artifacts
implementation 'com.squareup.okhttp3:okhttp'
implementation 'com.squareup.okhttp3:logging-interceptor'
//Coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2'
Chucker has two libraries i.e com.github.chuckerteam.chucker:library
and com.github.chuckerteam.chucker:library-no-op
. The latter is used to isolate Chucker from the release build.
This means if you fail to add the second library, Chucker will still work but it will be present in your release build. This is not encouraged due to some reasons that we will discuss in this article.
Also ensure Java 8 support is enabled by ensuring that the code below is present in your app-level build.gradle
file inside the android
block.
android {
...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
In the dependencies, we have added the OkHttp library because Chucker works with its interceptor. The coroutines library is added because OkHttp invokes network calls.
Network calls should be done in the background thread since they take some time before the response is returned. This might block the main thread if done in the main thread.
Using Chucker is very simple because once you have added the library to your gradle file, you only have to plug the ChuckerInterceptor
into the OkHttp client:
// OkHttp client
val okHttpClient = OkHttpClient.Builder()
.addInterceptor(ChuckerInterceptor(this))
.build()
This is enough to allow Chucker to record all the HTTP tasks that are being done by your OkHttp client in your app.
Features of Chucker library
The following are the features of Chucker that makes it the best choice for debugging applications that use the Okhttp client:
- Chucker is very easy to integrate since it only requires you to add two lines of library codes in your
build.gradle
file. - There is no customization needed when using Chucker.
- It is compatible with OkHTTP 4.
- It is compatible with API level 21 and higher hence can support a wide range of Android devices.
- It ensures empty release artifacts due to
library-no-op
library. - It has support for the showing images in the HTTP responses.
- It has support for custom decoding of HTTP bodies.
Configuring Chucker
With the instance of ChuckerCollector
, you can customize Chucker according to your needs. Use the following code snippet to create an instance of ChuckerCollector
:
// Chucker Collector
val myChuckerCollector = ChuckerCollector(
context = this, // Context on which you are
showNotification = true, // Boolean for showing Notification, set to true to show and false otherwise
retentionPeriod = RetentionManager.Period.ONE_WEEK // Period taken to retain the collected data, can be an hour, day or week
)
After creating the collector, we can then create the ChuckerInterceptor
which we will plug into the OkHttpClient
builder:
// Chucker Interceptor
val myChuckerInterceptor = ChuckerInterceptor.Builder(this) // `this` is the context
// The previously created ChuckerCollector
.collector(myChuckerCollector)
// The maximum body content length in bytes, after this responses will be truncated.
.maxContentLength(250_000L)
// List of headers to replace with ** in the Chucker UI
.redactHeaders("Auth-Token", "Bearer")
// Read the whole response body even when the client does not consume the response completely.
// This is useful in case of parsing errors or when the response body
// is closed before being read like in Retrofit with Void and Unit types.
.alwaysReadResponseBody(true)
.build()
We can then plug the interceptor into the OkHttp client builder as shown in the code snippet below:
// OkHttp Client
val client = OkHttpClient.Builder()
.addInterceptor(myChuckerInterceptor)
.build()
In the final part, we will create our OkHttp request for making network calls.
Remember to make the network calls inside a coroutine scope.
val request = Request.Builder()
.url("https://elephant-api.herokuapp.com/elephants/")
.build()
// OkHttp request should run in the Background thread hence Coroutines
CoroutineScope(Dispatchers.IO).launch {
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
e.printStackTrace()
}
override fun onResponse(call: Call, response: Response) {
if (response.isSuccessful) {
val myResponse: String? = response.body?.string()
// To access the TextView, switch to the Main thread
CoroutineScope(Dispatchers.Main).launch {
binding.textView.text = myResponse
}
}
}
})
}
Here is the full implementation of our MainActivity.kt
class:
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val okHttpClient = OkHttpClient.Builder()
.addInterceptor(ChuckerInterceptor(this))
.build()
// Chucker Collector
val myChuckerCollector = ChuckerCollector(
context = this,// Context on which you are
showNotification = true, // Boolean for showing Notification
retentionPeriod = RetentionManager.Period.ONE_WEEK // Period taken to retain the collected data
)
// OkHttp Client
val client = OkHttpClient.Builder()
.addInterceptor(myChuckerInterceptor)
.build()
// OkHttp network request
val request = Request.Builder()
.url("https://elephant-api.herokuapp.com/elephants/")
.build()
// OkHttp request should run in the Background thread
CoroutineScope(Dispatchers.IO).launch {
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
e.printStackTrace()
}
override fun onResponse(call: Call, response: Response) {
if (response.isSuccessful) {
val myResponse: String? = response.body?.string()
// To access the TextView, switch to the Main thread
CoroutineScope(Dispatchers.Main).launch {
binding.textView.text = myResponse
}
}
}
})
}
}
}
Conclusion
In this tutorial, we learned how to use Chucker when debugging. You can read further on mapping the JSON response to Kotlin objects using the Gson library.
Chucker is very simple to use and very efficient in debugging when performing network calls with the OkHttp client. Don't forget to look at the other debugging libraries like Timber and Stetho because they are also very useful in certain scenarios.
Happy Coding!
Peer Review Contributions by: Dawe Daniel