From Java to Kotlin (MVVM + Retrofit + Coroutines + Jetpack)
from the CommonsWare Community archivesAt September 26, 2020, 4:18pm, vedy asked:
Hi Mark,
I’m trying to convert an app from Java to Kotlin, a recipies app (RecyclerView with Recipe categories , calls an API to do recipe search , show recipes and display details of recipes), I believe the issues I’m facing are stemming from using retrofit with coroutines. specifically the use of suspend fun does not play very well with the other files in Java. But I have converted the relevant Java classes into Kotlin (using Android studio 4)
To paint a more concrete picture i’m rpoviding code snippets here:
- Here are the related retrofit classes
RecipeApi
[included in the link above] new users can only post 2 links
RecipeApiClient.kt
[included in the link above] new users can only post 2 links
ServiceGenerator.java
[included in the link above] new users can only post 2 links
- Here are the ViewModel and repo classes in Kotlin
RecipeViewModel.kt
[included in the link above] new users can only post 2 links
RecipeRepository.kt
[included in the link above] new users can only post 2 links
- This is how they looked like in Java
RecipeViewModel.java
[included in the link above] new users can only post 2 links
RecipeRepository.java
[included in the link above] new users can only post 2 links
- All seems to be well until I came across the conversion of the MainActivity, the converted Kotlin class is still giving errors related to it needs suspend function , but the MainActivity class resulting from doesn’t make sense to me.
This is the Java version of MainActivity
[included in the link above] new users can only post 2 links
and this is the Kotlin converted version
[included in the link above] new users can only post 2 links
My questions are:
- Are there any glaring mistakes I have made that stick out from the code above that I can fix?
- Do you recommend Java to Kotlin conversion using android studio at all? What issues I need to watch for not to get stuck again?
Thanks in advance and let me know if you need any more details
At September 26, 2020, 5:04pm, mmurphy replied:
I am happy to try to answer specific questions that you may have regarding your code (particularly if you put the code into your question here on this site). However, I am not offering a code review service.
the converted Kotlin class is still giving errors related to it needs suspend function
searchRecipeById() in RecipeViewModel is a suspend function. It needs to be called inside of a suitable CoroutineScope or to be called by another suspend function. Your activity is doing neither.
You have two main choices:
-
Do not expose a
suspend-based API to the activity. Instead, useviewModelScopeinside of yourViewModelto handle the coroutine and expose a traditional API. See https://gitlab.com/commonsguy/cw-jetpack-kotlin/-/blob/v1.1/DiceLight for an example from Elements of Android Jetpack that takes this approach. -
Use
lifecycleScopein your activity for calling thesuspendfunction. In https://gitlab.com/commonsguy/cw-jetpack-kotlin/-/tree/v1.1/NukeFromOrbit (from the same book), I take this approach for consuming events from aBroadcastChannel.
Do you recommend Java to Kotlin conversion using android studio at all?
The conversion works better than I would have expected, at least when I last used it (around 2 years ago). The resulting code usually compiles and frequently runs. However, for all but the simplest conversions, it usually needs some cleanup in order to become Kotlin that I would want to use long-term. For example, the converted code tends to use !! a lot, and that is a convenient yet unforgiving approach to dealing with nullable types.