우찬쓰 개발블로그

안드로이드에서 Kotlin Coroutine으로 Event Bus 구현 본문

안드로이드/안드로이드 개발

안드로이드에서 Kotlin Coroutine으로 Event Bus 구현

이우찬 2021. 4. 11. 19:01
반응형

현재 개발하고 있는 토이 프로젝트에 RxJava는 쓰지않는데 EventBus기능이 필요해졌다.

 

LocalBroadcastManager를 쓸수도 있겠지만, 이 클래스는 context를 필요로 하다보니 코드의 양이 늘어나는 문제도 있고, 현재 프로젝트의 아키텍쳐 구조를 헤칠것 같았다.

 

그래서 Coroutine에 있는 SharedFlow를 이용하여 EventBus를 구현해보기로 했다.

 

<현재 필요한 요구사항>

유저가 글쓰기를 하고나면, 다른 화면에서 이벤트를 받아서 리프레시 해주어야 한다.

 

Coroutine 공식 문서를 보면 EventBus에 대한 가이드를 어느정도 해주고 있다.

 

kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-shared-flow/

class EventBus {
    private val _events = MutableSharedFlow<Event>() // private mutable shared flow
    val events = _events.asSharedFlow() // publicly exposed as read-only shared flow

    suspend fun produceEvent(event: Event) {
        _events.emit(event) // suspends until all subscribers receive it
    }
}

 

이 코드를 입맛에 맞게 변형하여 필자는 아래와 같이 RefreshEventBus를 구현했다.

github.com/WoochanLee/CatHolic/blob/master/app/src/main/java/com/woody/cat/holic/framework/base/RefreshEventBus.kt

class RefreshEventBus {
    private val events = MutableSharedFlow<GlobalRefreshEvent>()

    fun produceEvent(event: GlobalRefreshEvent) {
        GlobalScope.launch {
            events.emit(event)
        }
    }

    suspend fun subscribeEvent(globalRefreshEvent: GlobalRefreshEvent, onEvent: () -> Unit) {
        events.filter { it == globalRefreshEvent }.collect { onEvent() }
    }
}

enum class GlobalRefreshEvent {
    LikedPostingChangeEvent,
    UploadPostingEvent
}

실제로 이벤트를 보내는 곳과, 이벤트를 받는 곳의 코드는 아래와 같다.

refreshEventBus.produceEvent(GlobalRefreshEvent.UploadPostingEvent)
private fun initEventBusSubscribe() {
    viewModelScope.launch {
        refreshEventBus.subscribeEvent(GlobalRefreshEvent.UploadPostingEvent) {
            initData()
        }
    }
}

구독시 viewModelScope를 사용하기때문에 lifecycle에 따라 자동으로 구독이 취소되도록 유도할 수 있다.

 

동작을 확인해보자.

 

업로드후 자동으로 게시물이 정보가 업데이트되어 다시 잘 받아오는것을 확인 할 수 있었다.

반응형
Comments