Android/Kotlin

안드로이드 코루틴 이벤트 버스

easy-1 2021. 11. 3. 14:52

<개요>

Activity 간 이벤트 전달을 위해 사용됨.

다른 Activity 에서 데이터 변경이 일어날 경우 메인이 되는 Activity 에서 구독을 통하여 이벤트 변경을 수신함.


<적용방법>

1. EventBus 클래스 생성

object EventBus {

    private val events = MutableSharedFlow<EnumEventBus>()
    val mutableEvents = events.asSharedFlow()

    suspend fun produceEvent(event: EnumEventBus) {
        events.emit(event)
    }

    inline fun <reified T> subscribe(): Flow<T> {
        return mutableEvents.filter { it is T }.map { it as T }
    }
}

// 이벤트 종류 구분
enum class EnumEventBus {
    EVENT1,
    EVENT2
}

2. 이벤트 구독

- viewModelScope 안에서 구독실행

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding
    private val viewModel by viewModels<MainViewModel>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)

        // Set Observer
        observerViewModel()
        // 이벤트 버스 구독
        viewModel.initEventBusSubscribe()
    }
    
    fun observerViewModel() {
        // ...
    }
}
@HiltViewModel
class MainViewModel @Inject constructor(
    private val service: RetrofitService
) : ViewModel() {

    // 이벤트 버스 구독
    fun initEventBusSubscribe() {
        viewModelScope.launch {
            EventBus.subscribe<EnumEventBus>().collect {
                if (it == EnumEventBus.EVENT1) {
                    // ... 
                }
            }
        }
    }
}

3. 이벤트 생성

- viewModelScope 에서 이벤트  실행

@AndroidEntryPoint
class SecondActivity : AppCompatActivity() {

    private lateinit var binding: ActivitySecondBinding
    private val viewModel by viewModels<SecontViewModel>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_second)

        // Set Observer
        observerViewModel()
        
        // 이벤트 실행
        viewModel.produceEvent()
    }
}
@HiltViewModel
class SecondViewModel @Inject constructor(
    private val service: RetrofitService
) : ViewModel() {

    // 이벤트버스 실행
    fun produceEvent() {
        viewModelScope.launch {
            EventBus.produceEvent(EnumEventBus.EVENT1)
        }
    }
}