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, useviewModelScope
inside of yourViewModel
to 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
lifecycleScope
in your activity for calling thesuspend
function. 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.