Android-CleanArchitecture
Android-CleanArchitecture copied to clipboard
Transforming to presentation model is done on UI thread, because of UseCase limitations
In your code, you transform domain entities into presentation model in UI thread, mainly because the UseCase can't access entities from presentation.
E.g. UserDetailsPresenter.java#L100, UserListPresenter.java#L109
Transformations in UI thread is not a really good idea, especially when we have the power of RxJava.
So, in my projects, a UseCase is an interface like this
interface UseCase<Params, T> {
fun buildUseCaseObservable(params: Params): Observable<T>
}
Mainly because I have the following cases. Here, I want to transform some data from repository model into presentation model, but I don't want to do it on UI thread, and I don't want to start another async procedure, or lose convenience of Rx transformation methods, so I apply transformations for the use case observable in my presenter.
disposable = useCase.buildUseCaseObservable(Unit)
.subscribeOn(schedulers.io())
.map { SectionedVideoListMapper.transform(it) }
.observeOn(schedulers.mainThread())
.subscribe(this::onDataLoaded, this::onDataLoadFailed)
Or here, I cannot pass Intent to domain layer to retrieve the video list, so I do this transformation off UI thread before passing it to UseCase.
Observable.fromCallable { PlaylistVideoMapper.transform(contentResolver, data) }
.subscribeOn(schedulers.io())
.flatMap { useCase.buildUseCaseObservable(CreatePlaylistUseCase.Params(name, it)) }
.observeOn(schedulers.mainThread())
.subscribe({}, this::onPlaylistCreateFailed)
What do you think about this approach?
@Doctoror I think it is up to. That's why RxJava is used here as a link between different layers because it makes it much easier to convert, adapt and manipulate data being passed. Furthermore one of the most valuable feature of RxJava is easy threading.
I think you are in the right track, the UI thread is a view layer detail and doesn't belong anywhere except in the UI layer, in my opinion.