배경
저는 이번에 FCM이 날아왔을 때 실시간으로 데이터가 변경되는 화면을 구현해야 했습니다. 처음에는 object 객체에 LiveData를 넣어 구현하였지만 LiveData를 object에 넣어 작업하면 lifecycle 문제가 발생할 것이라고 생각하였습니다.
다른 방식을 찾다보니 Event Bus를 활용하는 것이 좀 더 나은 방식이라고 판단하여 적용하게 되었습니다
설명에 앞서..
Event Bus 라이브러리에는 아래와 같이 2가지가 있습니다.
1. Square사의 Otto (https://github.com/square/otto)
2. greenbot의 EventBus (https://github.com/greenrobot/EventBus)
저는 2번를 사용하여 이것에 대해 정리해보고자 합니다.
Event Bus (green bot)
이벤트 버스란 Publisher가 Event를 post()하였을 때 각각의 Subscriber가 Event를 감지하는 것입니다. 이를 통해
각 노드들은 채널에 연결되어 있기만 하다면 쉽게 데이터를 전달받을 수 있습니다.
기존의 브로드 캐스트를 등록해 놓은 액티비티는 브로드 캐스트 리시버 객체의 onReceive 콜백의 Intent를 통해 데이터를 전달받고 여러개가 등록되어 있다면 분기도 필요합니다.
Activity와 Fragment의 통신도 브로드 캐스트를 활용할 수 있지만, 인텐트에 클래스 객체를 전달하려면 Parcelable을 사용해야 하는 귀찮은 점이 존재합니다.
깃허브 설명에 의하면 이벤트 버스는 아래와 같은 장점이 있습니다.
- 컴포넌트들 사이에서의 커뮤니케이션을 단순화합니다
- 이벤트 발신자와 수신자 분리
- 활동, 프래그먼트 및 백그라운드 스레드에서 잘 수행
- 복잡하고 오류가 발생하기 쉬운 종속성 및 수명 주기 문제 방지
- 코드를 단순화
- 빠르고, 작다
- 전달 스레드, 구독자 우선 순위 등과 같은 고급 기능
Event Bus 적용해보기
1. build.gradle(Module: app)의 dependencies에 아래와 같이 추가합니다
implementation 'org.greenrobot:eventbus:3.3.1'
저는 예시를 보이기 위해 MainActivity 위(FirstFragment) / 아리 (SecondFragment)로 나눠서 SecondFragment의 버튼을 클릭 시 FirstFragment의 데이터가 변동되는 것을 보여드리겠습니다
2. Event를 위한 class 작성
data class NumData(var count: Int)
3-1. FirstFragment 설정
Post된 데이터를 수신받고자 하는 Activity나 Fragment의 onStart, onStop에 붙여주시면 됩니다.
@Subscribe 가 붙은 함수는 Post되었을 때 반응하는 함수입니다.
( UI 변경을 위해 MainThread를 사용했습니다)
class FirstFragment : Fragment() {
...
@Subscribe(threadMode = ThreadMode.MAIN)
fun onButtonClickEvent(data: NumData) {
binding.clickCount.text = data.count.toString()
}
override fun onStart() {
super.onStart()
EventBus.getDefault().register(this)
}
override fun onStop() {
super.onStop()
EventBus.getDefault().unregister(this)
}
}
3-2. Second Fragment 설정
Event.getDefault().post(데이터) 로 보내면 Subscriber들이 event를 받게 됩니다.
(post 안에 String은 보낼 수 있었지만 int는 반응하지 않았습니다 - 개인적인 테스트)
class SecondFragment : Fragment() {
...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val numData = NumData(0)
binding.button.setOnClickListener {
numData.count+=1
EventBus.getDefault().post(numData)
}
}
}
이렇게 설정해주시면 간단하게 EventBus를 사용할 수 있습니다. 하지만 이것은 EventBus를 사용하기 위한 예시로서 Fragment 사이의 data transfer를 보여드린 것이고 setFragmentResultListener(), viewModel 등등을 활용하여 데이터 처리하는 방식을 저는 좀 더 추천 드립니다.
<안드로이드 공식 홈페이지 - Fragment data transfer>
<EventBus 구현 Github 링크>
<블로그 정리 참조 링크>
https://no-dev-nk.tistory.com/19
https://doitddo.tistory.com/71
'Android' 카테고리의 다른 글
[Android] ScrollView 내 레이아웃 높이 가득 채우기 (0) | 2022.08.06 |
---|---|
[Android] findViewById는 어떻게 동작하는걸까? (0) | 2022.08.06 |
[Android] 기본 구분선 추가하기 (0) | 2022.07.23 |
[Android Kotlin] Google Login & registerForActivityResult (0) | 2022.07.20 |
[Android] java.lang.IllegalStateException: Already executed (0) | 2022.07.18 |
댓글