관리 메뉴

막내의 막무가내 프로그래밍 & 일상

[안드로이드] BaseViewModel 기본적인 Rx 서버 통신 작업을 위한 공통 함수 기록 본문

안드로이드/RxJava

[안드로이드] BaseViewModel 기본적인 Rx 서버 통신 작업을 위한 공통 함수 기록

막무가내막내 2021. 6. 3. 18:39
728x90

 

RxJava 를 다양하게 사용하겠지만 단순 네트워크 통신으로 사용시 코드가 길어지는 경향이 있어

이를 BaseViewModel 에서 공통 함수를 만들어 사용하면 좋지 않을까 하고 만들어봤습니다. 

RxJava를 더 간단하게 작업하기 위해 Wrapping 하는 정석적이거나 많이 사용하는 코드가 있을거 같은데 아직 찾지 못하여 내가 그냥 간단히 만들고 기록해봄당..

 

 

만든 샘플 예제 코드는 다음과 같습니다. 

1. Single, Flowable, Completable 의 기본적인 네트워킹 작업에 대한 Base excute() 메소드

2. 이 BaseViewModel 을 상속후에 어떻게 활용하는지 exampleXXXXcall() 메소드로 예제

덕분에 빠르게 개발하고 기본적인 네트워킹 작업이 많은 경우 두 줄만으로 작업을 할 수 있을 것 같습니다 :)

주석도 적혀있고 기본적인 코드라 이해하기 어렵진 않습니다.

 

import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.mtjin.nomoneytrip.data.home.Product
import com.mtjin.nomoneytrip.utils.TAG
import io.reactivex.Completable
import io.reactivex.Flowable
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.addTo
import io.reactivex.rxkotlin.subscribeBy
import io.reactivex.schedulers.Schedulers

abstract class BaseViewModel : ViewModel() {
    protected val compositeDisposable = CompositeDisposable()


    val _productListLiveData = MutableLiveData<List<Product>>()
    val _errorMessageLiveData = MutableLiveData<String>()
    val _isSuccess = MutableLiveData<Boolean>()

    val _loading = MutableLiveData<Boolean>()
    val loading: LiveData<Boolean> get() = _loading

    // 일반적인 네트워크 통신시 사용할 base 통신 함수
    protected fun <T : Any> excute(
        single: Single<T>,
        res: (T) -> Unit,
        isShowLoad: Boolean = true
    ) {
        single.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .doOnSubscribe { if (isShowLoad) _loading.value = true }
            .doAfterTerminate { if (isShowLoad) _loading.value = false }
            .subscribeBy(onSuccess = {
                res(it)
            }, onError = {// 에러나면 해당 에러메시지 토스트메시지로 띄워줌
                Log.e(TAG, "ViewModel Single Excute() onError -> " + it.message)
                _errorMessageLiveData.value = it.message
            })
            .addTo(compositeDisposable)
    }

    protected fun <T : Any> excute(
        flowable: Flowable<T>,
        res: (T) -> Unit,
        isShowLoad: Boolean = true
    ) {
        flowable.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .doOnSubscribe { if (isShowLoad) _loading.value = true }
            .doAfterTerminate { if (isShowLoad) _loading.value = false }
            .subscribeBy(onNext = {
                res(it)
            }, onComplete = {
                Log.d(TAG, "ViewModel Flowable Excute() onComplete -> " + it.message)
            }, onError = {// 에러나면 해당 에러메시지 토스트메시지로 띄워줌
                Log.e(TAG, "ViewModel Flowable Excute() onError -> " + it.message)
                _errorMessageLiveData.value = it.message
            })
            .addTo(compositeDisposable)
    }

    protected fun excute(
        completable: Completable,
        res: (Boolean) -> Unit,
        isShowLoad: Boolean = true
    ) {
        completable.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .doOnSubscribe { if (isShowLoad) _loading.value = true }
            .doAfterTerminate { if (isShowLoad) _loading.value = false }
            .subscribeBy(onComplete = {
                res(true)
            }, onError = {// 에러나면 해당 에러메시지 토스트메시지로 띄워줌
                Log.e(TAG, "ViewModel Completable Excute() onError -> " + it.message)
                _errorMessageLiveData.value = it.message
            })
            .addTo(compositeDisposable)
    }

    // Single 호출 방법예시
    fun exampleSingleCall() {
        excute(repository.requestProducts(), { items ->
            _productListLiveData.value = items
        })
    }

    // Flowable 호출 방법예시
    fun exampleFlowableCall() {
        excute(repository.requestProducts(), { items ->
            _productListLiveData.value = items
        })
    }

    // Completable 호출 방법예시
    fun exampleFlowableCall() {
        excute(repository.requestProducts(), { success ->
            _isSuccess.value = success
        })
    }

}

 

 

 

댓글과 공감은 큰 힘이 됩니다. 감사합니다. !!

728x90
Comments