Simple Android — 1

Hacı Kanal
2 min readDec 6, 2022

Android in a nutshell

Code Complexity vs. Experience — (Image — flaviocopes)

For the past decade, we have seen a lot of milestones in Android Application Development and I mostly found them pragmatic and they left positive impact among Developers and Users.

However, I recently realized that I am wasting my time searching things than focusing on the main objective, the app I am developing.

All the things that we are desperately try to use feels like a burden, far from the objective and many of these Patterns, Architectures, Principles and third parties are leading us to over-engineering and/or burnout, not because they are not good or they are useless. There are bunch of ways to achieve something and people get confused or waste their time.

It must be hard to be a junior nowadays.

That being said, one simple job for almost all android apps is sending http request. Oh man, I know what I have been through with Apache, Volley, Retrofit. It is just a simple request/response.

Note: The examples I will give you now, not a replacement for another or not a comparison between tools.

One Simple Job — Http Requests

I am pretty sure most of us using Retrofit, OkHttp, Gson and Api Interfaces by injecting with Hilt/Dagger2.

Because of my past experiences, this combination is tightly-coupled and when you need a dynamic client for advanced usage of hosts, you will be suffering to try to find an optimized way for your intended use and apply it to DI graph, also your Architecture.

What I can recommend is Ktor Android Client.

I recently created myself a Network Dispatcher that allows me to make http connections in a few minutes, no more unnecessary interfaces or classes

Http base

object Ktor {

val client = HttpClient(OkHttp) {
engine {
config {
connectTimeout(30_000, TimeUnit.MILLISECONDS)
}
addNetworkInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
})
threadsCount = 4
}
install(ContentNegotiation) {
json(Json {
prettyPrint = true
ignoreUnknownKeys = true
})
}
install(DefaultRequest) {
headers {
append(HttpHeaders.Accept, ContentType.Text.Plain)
append(HttpHeaders.ContentType, ContentType.Application.Json)
}
url(ENDPOINT)
}
Charsets {
register(Charsets.UTF_8)
}
HttpResponseValidator {
handleResponseExceptionWithRequest { cause, request->

}
}
expectSuccess = true
}
}

This is completely optional, I needed it.

@Singleton
class Dispatcher @Inject constructor() {

val client = Ktor.client

suspend inline fun getRequest(block: HttpRequestBuilder.(HttpRequestBuilder) -> Unit): HttpResponse {
val builder = HttpRequestBuilder()
builder.block(builder)
return client.get(builder)
}
}

And send the request, simply.

suspend fun userRequest(userId: Long) =
dispatcher.getRequest {
url {
path("/user")
parameter(USER_ID, userId)
}
}.body<UserResponse>()

Today’s thread is all about that, hope to see you for the second part.

https://www.mindtheproduct.com/overengineering-can-kill-your-product/

https://ktor.io/docs/welcome.html

https://kotlinlang.org/docs/serialization.html

https://square.github.io/okhttp/

--

--

Hacı Kanal

Android Developer currently at Adesso Turkey, Retired Indie Game Developer, Amateur endurance cyclist