Blog Infos
Author
Published
Topics
, , , ,
Author
Published

This will be the fifth installment in our series “Mastering Android ViewModels” where we dive deep into the essential dos and don’ts that can elevate your Android development skills. We’ve already covered several tips to improve performance and code quality in ViewModels, which have become an integral part of modern Android applications.

We’ve Covered So Far 🔄🔄🔄
  1. Avoid initializing the state in the init {} block. ✅ Read here
  2. Avoid exposing mutable states. ✅ Read here
  3. Use update{} when using MutableStateFlows. ✅ Read here
  4. Try not to import Android dependencies in the ViewModels. ✅ Read here
  5. Lazily inject dependencies in the constructor. ✅ Read here
  6. Embrace more reactive and less imperative coding. ✅ Read here
  7. Avoid initializing the ViewModel from the outside world. ✅ Read here
In this article we’ll cover:

8. 👉Avoid hardcoding Coroutine Dispatchers.

9. 👉Unit test your ViewModels.

10. 👉Avoid exposing suspended functions.

#8 — Avoid Hardcoding Coroutine Dispatchers

When dealing with coroutines in your ViewModel, hardcoding dispatchers like Dispatchers.IO or Dispatchers.Default might seem convenient, but it can lead to tightly coupled and less testable code.

The Problem with Hardcoding Dispatchers

Hardcoding dispatchers directly in your ViewModel can make testing difficult and reduce flexibility. For instance, during testing, you may want to control the threading behavior, which becomes challenging with hardcoded dispatchers.

Recommended Approach

Inject your dispatchers via the constructor or use a dependency injection framework like Hilt or Dagger. This not only makes your ViewModel more flexible but also simplifies testing:

class MyViewModel(
    private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
) : ViewModel() {

  private fun loadData() {
     viewModelScope.launch(ioDispatcher) {
       // Your coroutine code here
     }
  }
}

By using dependency injection, you can swap out the dispatcher during testing, ensuring your ViewModel behaves correctly in different environments.

for an example look at:

https://github.com/LloydBlv/GoodDictionary/blob/main/ui/words-list/src/test/java/com/example/words_list/WordsListViewModelTest.kt?source=post_page—–14d04ec2426a——————————–

Job Offers

Job Offers

There are currently no vacancies.

OUR VIDEO RECOMMENDATION

No results found.

Jobs

#9 — Unit Test Your ViewModels

Unit testing is essential to ensure your ViewModels behave as expected. Without proper tests, you risk introducing bugs that could have been caught early.

Testing Challenges

ViewModels often interact with complex state and other components, making them tricky to test. However, by following the right practices, specially what we discuss in this series, you can thoroughly test your ViewModel’s logic.

Best Practices for Testing ViewModels
  • Use a TestCoroutineDispatcher to control coroutine execution and test asynchronous code synchronously.
  • Favor testing ViewModels as a non-Android test (use test folder instead of androidTest)
  • Avoid using runBlocking{} for testing suspended functions, instead use runTest{} from coroutines-test
  • Avoid manually peeking values from StateFlows, Use Turbine instead
  • For testing flows, use Turbine
  • Favor fakes over mocks
#10 — Avoid Exposing Suspended Functions

While suspend functions make asynchronous programming in Kotlin easier, exposing them directly from your ViewModel can lead to misuse and increased complexity.

Why It’s Problematic

Exposing suspend functions can result in mismanagement of threading or lifecycle events, leading to bugs or crashes.

The Better Way

Keep suspension internal to the ViewModel, and expose results through Flow or other observable patterns.

Conclusion:

Mastering ViewModels in Android development is crucial for creating robust, efficient, and maintainable applications. Throughout this series, we’ve discussed a comprehensive set of best practices to improve your code quality and application performance.

🌟 Congratulations if you’ve made it this far in the article! 🎉 Don’t forget to:

  • 👏 smash the clap button as many times! So I can continue with the follow-up articles!
  • Follow my YouTube channel for video tutorials and tips on Android development
  • ✨✨ If you need help with your Android ViewModels, Project, or your career development, Book a 1:1 or a Pair-Programming session with me, Book a time now 🧑‍💻🧑‍💻🧑‍💻
  • check out the previous articles in this series with the links below:

https://proandroiddev.com/mastering-android-viewmodels-essential-dos-and-donts-part-1-%EF%B8%8F-bdf05287bca9?source=post_page—–14d04ec2426a——————————–

https://proandroiddev.com/mastering-android-viewmodels-essential-dos-and-donts-part-2-%EF%B8%8F-2b49281f0029?source=post_page—–14d04ec2426a——————————–

https://proandroiddev.com/mastering-android-viewmodels-essential-dos-and-donts-part-3-%EF%B8%8F3%EF%B8%8F%E2%83%A3-1833ce3ddd2b?source=post_page—–14d04ec2426a——————————–

https://proandroiddev.com/mastering-android-viewmodels-essential-dos-and-donts-part-4-%EF%B8%8F-a0bad53cebd2?source=post_page—–14d04ec2426a——————————–

This article is previously published on proandroiddev.com

YOU MAY BE INTERESTED IN

YOU MAY BE INTERESTED IN

blog
It’s one of the common UX across apps to provide swipe to dismiss so…
READ MORE
blog
Hi, today I come to you with a quick tip on how to update…
READ MORE
blog
Automation is a key point of Software Testing once it make possible to reproduce…
READ MORE
blog
Drag and Drop reordering in Recyclerview can be achieved with ItemTouchHelper (checkout implementation reference).…
READ MORE
Menu