1

I am building a Custom View in a library module that every 30 seconds displays a question (obtained from a REST Api) and allows the user to select one of the possible answers.

I need to make use of that library in the app module. The only thing that the MainActivity from the app module should do is to display a video and add the Custom View on top of it.

All the business and UI logic should be handled in the library (fetching the questions from the server, handling a timer, handling the answer selected, etc.)

So the app consists of only one Activity and the library consists of a CustomView, a usecase, a repository, and an ApiService class to make the Api request using retrofit.

Since the library doesn't have a ViewModel (because there are no Fragments or Activities in the library module), I am executing the usecase from the CustomView.

CustomView --> UseCase (launches couroutine) --> Repository --> RetrofitService

Is there a cleaner/proper way to do this? I've been told that calling an api from the view is a very bad practice, but I don't know any other way to do it at the moment.

Praveen P.
  • 976
  • 2
  • 11
  • 23

2 Answers2

0

A custom View should not hold the data at all. Custom view couldn't handle the view recreation, for example. The proper way is to use a Fragment instead of the custom view.

Diniz
  • 155
  • 1
  • 4
0

The co-routine runs asynchronous; while not accessing the network from the UI thread, this isn't an issue (one just can't do that, it's strictly forbidden). Retrofit by itself already executes asynchronous in Java, therefore I'd wonder if an extra co-routine is required. Adding keyword suspend to the interface definition's methods should suffice to make both work in unison. LiveData would be the preferred way of updating the view, but in Kotlin one could as well use the same asynchronous call-backs as in Java. Also see: What does the suspend function mean in a Kotlin Coroutine?

Martin Zeitler
  • 1
  • 19
  • 155
  • 216
  • I see, so there's no need of using coroutines if I am using retrofit. Would you still add the use case and repository layers? Or should I leave it as simple as possible? – Praveen P. Oct 01 '20 at 20:46
  • Retrofit with GSON, `suspend` (coroutine) & `LiveData` might be the most design-guidelines conform. These common Java asynchronous callbacks are represented Kotlin-idiomatic as coroutines. Without `suspend` it might be a blocking call, even if Retrofit has asynchronous callbacks. – Martin Zeitler Oct 01 '20 at 22:11
  • I mean, when writing in Kotlin, one should better use Kotlin idiomatic language. – Martin Zeitler Oct 01 '20 at 22:21