본문 바로가기

안드로이드/팁

Livedata(MVVM) + RxAndroid 사용시 주의 사항

반응형

mvvm 패턴으로 간단한 rxAndroid와 함께 사용하여 식물관리 앱을 개발중입니다. mvp를 처음 도입할때도 그랬지만 많은 시행 착오를 겪고 수정하면서 체계를 잡아가고 있습니다. 그러던중 주의해야할 상황이 생겨 공유 및 복기 목적으로 남깁니다.

 

먼저 rxAndroid를 엑티비티 라이프사이클에 맞춰 메모리 누수를 막기위한 용도로 마이너하게 사용하고 있습니다. 잘못되게 사용하고 있다면 댓글 및 방명록으로 지적해주시면 감사하겠습니다.

※사용중인 라이브러리 - Livedata, viewModel(AAC), rxAndroid, kotlin, koin, room

> 앱 설명 + 상황

'식물관리'앱의 메인에는 식물 리스트가 좌측에 위치하고 리스트중 선택한 식물의 정보가 우측에 존재합니다. 그리고 우측화면 하단엔 선택한 식물의 달력 정보를 노출하고 있습니다.

※디비구조는 크게 식물,달력이고 식물디비 id컬럼과 달력디비 식물id컬럼이 join상태입니다. 

메인 화면

위 구조처럼 되어 있다보니 처음 메인에 진입했을때 식물 리스트를 불러오고, 선택한(default index 0) 식물의 달력 정보를 불러옵니다.

	// 달력 정보 불러오기
    private fun selectDiaryList(year: Int, month: Int) {
        addDisposable(
            repo.getDiaryList(year, month, selectPlant.value?.id ?: 0)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe {
                    diaryList.value = it
                }
        )
    }
    // 식물 불러오기
    private fun selectPlantList() {
        addDisposable(
            repo.getPlantList()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe {
                    plantList.value = it
                    selectPlant(selectPlantIndex)
                }
        )
    }

Disposable을 추가해 생명주기에 맞춰 메모리에 할당하고 해제하는 작업을 거치는데 문제가 발생했습니다.

달력 정보를 업데이트했을때 selectDiaryList 메소드내 subscribe가 자동적으로 호출됐는데, 문제는 식물 리스트를 각각 선택한 수대로 호출되는 문제가 있었습니다. 

예 ) 식물 리스트들중 1,2,4번째를 선택해 각각의 달력 정보가 갱신되는걸 확인하고 4번째 식물의 달력 정보를 업데이트 했을때 기존에 호출된 1,2,4번쨰 달력 리스트가 호출되 4번째 식물의 달력을 보여줘야 하는데 1번째 식물의 달력을 보여준다는등 다른 식물의 달력이 보이거나 다른 식물의 달력이 보였다가 4번쨰 식물의 달력이 보이는 이슈가 있었습니다.

문제 요약 : 다른 식물들의 정보가 혼용해서 보인다.

> 원인 분석

viewModel에서 관리되고 있는 식물 리스트와 달력 리스트(liveData)를 엑티비티 onCreate에서 구독하고 있는 상태로 식물을 선택할따마다 기존에 구독된 정보를 해제하고 재 구독해주는 코드로 작성해봤는데도 동일하게 작동했습니다.

그러다 발견한게 달력 정보를 가져오는 disposable을 추가해주는 코드가 문제였습니다. ( 위 코드에서 'selectDiaryList(year:Int,month:Int)' 

식물을 변경할때마다 해당 dispoable을 계속 추가해주다보니 달력 정보를 변경할때마다 추가된 dispoable 수대로 호출되고 있었습니다. 

> 해결

disposable을 변수로 만들어 추가하기전에 체크해서 해제하고 재 추가하는 방향으로 변경하니 문제는 해결됐습니다.


    private var selectDiaryDisposable : Disposable? = null
  
   fun selectDiaryList(year: Int, month: Int) {

        selectDiaryYear.value = year
        selectDiaryMonth.value = month

        selectDiaryDisposable?.dispose()
        selectDiaryDisposable = repo.getDiaryList(year, month, selectPlant.value?.id ?: 0)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                diaryList.value = it
            }

        addDisposable(selectDiaryDisposable!!)
    }

 

mvp패턴때 사용하던 방식을 차용하는 과정에서 겪은 문제로 저와 같은 문제를 겪으시는 분들이 조금이라도 빨리 문제를 해결하시는데 도움이 됐으면 좋겠습니다.

 

위의 식물앱은 아직 미출시 앱으로 올해 안에 출시하는게 목표입니다. 

 

궁금하신 내용들은 댓글을 통해 남겨주세요

 

반응형