Simple Android — 2

Abusive usage of Frameworks and Libraries

Hacı Kanal
2 min readSep 26, 2023

In the past, we, as android developers, didn’t have so many options to achieve something that fulfills our requirements or they were not our first options because who wants to use some old fashioned frameworks or concepts, right?

That being said, we now have many frameworks or libraries or even good programming languages that are really powerful.

This considerable amount of tools, increases the complexity with the wrong usage like “Hey, this tool is awesome, I can use that here, here and here also here”. Soon you are realizing that your codebase is getting more confusing day by day. If you are familiar to android techs, I know what you are thinking now, StateFlow, SharedFlow, RxJava, Coroutines, LiveData, Arrow, and their tens of extension libraries and so on.

For today, I want to focus on abusive usage of Kotlin collections, Flow and wrong usage of SQLite then how it increases the complexity.

Sample 1 — Accessing the User and UserPosts

@Query("SELECT * FROM user")
fun getAll(): Flow<List<User>>
@Query("SELECT * FROM userposts")
fun getAll(): Flow<List<UserPosts>>
coroutineScope.launch {
users.combine(posts) { users, posts ->
val currentUser = users.firstOrNull { user -> user.uid == loggedUserId }
currentUser?.let {
val userPosts = posts.filter { post -> post.userId == currentUser.uid}
UserAndPosts(currentUser.uid, currentUser.firstName, currentUser.lastName, userPosts)
}
}.collect { userWithPosts ->
userWithPosts?.let { notifyScreen(it) }
}
}

This one is just a simple usecase, now imagine you have hundreds usecases, local data sources and viewModels do the similar filterings, mappings, and one day there will be new filtering requirement asked from business.

At this point, you are not sure that where you can add new filterings without breaking other functionalities, and you will think that this is too risky and duplicating the usecase is a good solution for bug free solution, and soon you will be having usecases 99% same logic and you increased complexity and you caused a mess.

How to avoid this?

Simple! just use your tools correctly!

First, create another Dao or function that has correct usage of SQLite

@Query(
"SELECT * FROM user" +
" JOIN userposts ON userposts.userId = user.uid WHERE user.uid =:uid"
)
fun loadUserAndPosts(uid: Int): Flow<Map<User, List<UserPosts>>>

Then use it like a boss!

coroutineScope.launch {
userAndPosts.collect { userAndPost ->
notifyScreen(userAndPost)
}
}

From the example, you might think that this is not a big issue but in a big project remember that you will have hundreds objects for those type of work and adding new properties to existing classes is mess!

Last words of today, “Abusive usage of Frameworks and Libraries” is a serious topic. I think we all suffer from this, feel free to contribute to this post with other tools!

https://developer.android.com/kotlin/flow

https://developer.android.com/training/data-storage/room

https://developer.android.com/training/data-storage/room/relationships

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Hacı Kanal
Hacı Kanal

Written by Hacı Kanal

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

No responses yet

Write a response