마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

액티비티위에 프래그먼트 postvalue? setvalue?

0 추천
A액티비티 위에 뷰페이저로  B,C,D 프래그먼트가 얹어져있고 A액티비티에서 코루틴으로 api 호출 response값을 data라는 변수에 postvalue,
B프래그먼트에서 data.value ?: throw null data
이렇게 처리해둔 상태인데 많이 죽지는 않지만 1주에 1명?정도 꾸준히 크래시가 나고있습니다 재현은 안됐구요 재현해볼방법이나 아니면 postvalue대신 setvalue를 써야되야할까요..? B프래그먼트가 들어가자마자 보이는 구조입니다
수원통학러 (3,570 포인트) 님이 2022년 4월 25일 질문

1개의 답변

0 추천

postValue와 setValue의 차이점은 아시리라 생각합니다. recap하면,

postValue - 쓰레드에 안전하게 데이터를 전달할 수 있다. 이 메소드를 사용하면 데이터는 먼저 큐에 쌓이고 나서 후에 처리된다. 만약 아직 큐에 데이터가 존재할 때, 다른 데이터가 들어오면 기존 데이터는 무시되고 나중의 데이터만 보관된다.

setValue - 메인쓰레드에서만 사용할 수 있다. 메인쓰레가 아닌 곳에서 사용하면 에러가 발생한다. 이 메소드를 이용하면 대기없이 데이터가 바로 전송된다.

한쪽에서 setValue를 하고 다른 곳에서 getValue로 값을 읽어오게 되면 위에 설명드린 부분때문에 null이 리턴될 수 있습니다. 해결책은 말씀하신 대로 setValue를 하시는 것이 가장 간단한 해결책일 듯 합니다. 다른 옵션으로는 데이터를  캐시를 하고 캐시를 공유할 수도 있습니다.

살짝 트릭을 사용하면, 이런 방법도 사용할 수 있습니다. 딱히 권하고는 싶지 않지만, 꼭 필요하시다면 검토해 보세요.

class BackeValueMutableLiveData(initialValue: T?): MutableLiveData<T>(initialValue) {

    private var backedValue: T? = initialValue

    override fun setValue(value: T?) {
       backedValue = value
       super.postValue(value)
    }

    override fun setValue(value: T?) {
       backedValue  = value
       super.setValue(value)
    }

    override fun getValue(): T? {
       return supert.getValue() ?: backedValue
    }
}

 

spark (226,720 포인트) 님이 2022년 4월 25일 답변
...