[안드로이드] EventBus 활용법

동현·2024년 5월 31일
1
post-custom-banner

1. 이벤트 버스란?

이벤트 버스는 애플리케이션의 여러 컴포넌트 사이에서 데이터 이벤트를 전달하는 역할을 하는 시스템이다.

그림과 같이 3개의 구성요소로 이루어져 있다.

  1. 발행자 (Publisher) : 이벤트를 생성하고 이벤트 버스에 전송
  2. 이벤트 버스 : 이벤트를 수신하고 해당 이벤트를 구독하는 컴포넌트에 전달
  3. 이벤트 구독자 : 특정 유형의 이벤트에 대한 알림을 받고 반응하는 컴포넌트

2. 활용 사례

그래서 이 이벤트 버스를 어떤 상황에 활용할 수 있을까...???
이벤트 버스는 컴포넌트 간의 상호작용에 모두 활용할 수 있지만, 전혀 관련이 없는 컴포넌트들 간의 상호작용에 있어서 가장 빛을 발한다고 생각한다!!

나의 경우, 한 화면에서의 이벤트가 다른 화면에 영향을 줄 때 사용한다.

예를 들어, 인스타의 팔로우/팔로우 취소 이벤트가 있다.
유저의 팔로잉 목록 -> 상대방 프로필 이동 후 팔로잉 취소 -> 뒤로 가기
상대방 프로필 화면에서 발생한 팔로잉 취소 라는 이벤트가 이전 화면인 유저의 팔로잉 목록 화면에 영향을 미친다!

3. 구현

그래서 이를 안드로이드에서 어떻게 구현할 수 있냐면.... SharedFlow를 통해서 구현할 수 있다!!

SharedFlow 는 동일한 이벤트를 여러 구독자에게 동시에 전송할 수 있는 멀티캐스팅을 지원하며, replayCache 를 통해 최근에 발생한 이벤트들을 일정 수만큼 캐싱 처리해, 새로운 구독자가 발생하더라도 해당 이벤트들을 즉시 받아보도록 할 수 있다.

object EventBus {

    private val _events = MutableSharedFlow<UserEvent>()
    val events = _events.asSharedFlow()

    suspend fun postEvent(event: Event) {
        _events.emit(event)
    }

    suspend inline fun <reified T> subscribeEvent(
        crossinline onEvent: (T) -> Unit
    ) {
        events.filterIsInstance<T>()
            .collect { event ->
                coroutineContext.ensureActive()
                onEvent(event)
        }
    }

}
sealed class Event {
    data class FollowUserEvent(
        val userId: Int,
        val isFollowed: Boolean
    ) : Event()
}

이를 이용해 발행자의 경우 postEvent, 수신자의 경우 subscribeEvent 를 통해 이벤트를 수신할 수 있다.

class FollowListViewModel : ViewModel() {
	
    init {
        viewModelScope.launch {
            UserEventBus.subscribeEvent<UserEvent> { event ->
                when (event) {
                    is Event.FollowUserEvent -> {
                        // 유저 목록을 보여주는 상태값 변경
                    }
                }
            }
        }
    }
    
}
class OpponentProfileViewModel : ViewModel() {
	
    fun modifyFollwStatus(targetUserId: Int, isFollowed: Boolean) {
        UserEventBus.postEvent(
            Event.FollowUserEvent(
                targetUserId,
                status == FollowStatus.FOLLOW
            )
        )	
    }
    
}

앞서 예시를 들었던 인스타 팔로잉 취소 이벤트를 구현한 예시이다.
object로 EventBus를 구현했기 때문에, 원하는 곳에서 EventBus의 메소드를 호출할 수 있다.

profile
https://github.com/DongChyeon
post-custom-banner

0개의 댓글