비동기 데이터 처리 라이브러리인 AAC LiveData와 Kotiln Flow를 비교해 볼 것이다.
요즘 뜨고있는 Chat GPT를 활용해서 작성해봤다.
LiveData
LiveData를 Chat GPT한테 물어보면 위와 같은 답변을 해준다.
Chat GPT가 한 말을 정리하자면 LiveData는 안드로이드의 LifeCycle을 인식해서 생명주기에 맞게 뷰가 Destroy되거나 비활성화 되면 Observing을 중단한다. 따라서 메모리 누수가 없고 뷰의 종료로 인한 충돌이 없다.
안드로이드에서 대부분 MVVM 아키텍쳐를 사용하고 있고 LiveData를 통해 ViewModel에서 View로 데이터를 통신하거나 전송한다.
ViewModel의 LiveData를 View에서 Observing해서 데이터의 변화를 감지하고 업데이트 해준다.
공식 문서에 따르면 다음과 같은 장점을 가지고 있다.
- UI와 데이터 상태의 일치 보장
LiveData는 Observer 패턴을 따른다. LiveData는 기본 데이터가 변형될 때 Observer 객체에 알리고, Observer는 UI를 업데이트 할 수 있다. 이렇게 하면 앱 데이터가 변경될 때마다 Observer가 UI를 업데이트 하므로 개발자가 직접 업데이트 할 필요가 없다. - 메모리 누수 없음
Observer는 Lifecycle 객체에 결합되어 있으며 연결된 수명 주기가 끝나면 자동으로 삭제된다. - 중지된 활동으로 인한 비정상 종료 없음
활동이 백 스택에 있을 때를 비롯하여 Observer의 수명 주기가 비활성 상태에 있으면 Observer는 어떤 LiveData 이벤트도 받지 않는다. - 수명 주기를 더 이상 수동으로 처리하지 않음
UI 구성요소는 관련 데이터를 관찰하기만 할 뿐 관찰을 중지하거나 다시 시작하지 않는다. LiveData는 관찰하는 동안 관련 LifeCycle 상태의 변경을 인식하므로 이 모든 것을 자동으로 관리한다. - 최신 데이터 유지
수명 주기가 비활성화되면 다시 활성화될 때 최신 데이터를 수신한다. 예를 들어 background에 있었던 활동은 foreground로 돌아온 직후 최신 데이터를 받는다. - 적절한 구성 변경
기기 회전과 같은 configuration 변경으로 인해 Activity 또는 Fragment가 다시 생성되면 사용 가능한 최신 데이터를 즉시 받게 된다. - 리소스 공유
앱에서 시스템 서비스를 공유할 수 있도록 싱글톤 패턴을 사용하는 LiveData 객체를 확장하여 시스템 서비스를 래핑할 수 있다. LiveData 객체가 시스템 서비스에 한 번 연결되면 리소스가 필요한 모든 Observer가 LiveData 객체를 볼 수 있다. 자세한 내용은 LiveData 확장을 참고하면 된다.
음 아직까진 LiveData가 뭔지 확 와닿지 않는다.
그래서 Chat GPT한테 물어봤다.
Chat GPT가 설명해준대로 ViewModel에서 값을 변경하면 변경된 값을 LiveData 객체에 담고 MainActivity에서는 ViewModel의 LiveData를 Observe해서 변한 값을 TextView에 담아준다.
View에서 바로 데이터를 변경해도 되지만 굳이 이렇게 분리하는 이유는 MVVM 아키텍쳐 패턴을 따르기 위한 것이다.
이렇게 분리 시키면 UI와 데이터 로직이 나뉘게 되면서 종속성이 사라지게 된다.
Kotlin Flow
LiveData와 마찬가지로 비동기 데이터 처리 라이브러리인 Kotlin Flow도 물어보자
LiveData와 같은 방식으로 데이터를 처리해주지만 Kotlin Flow는 코루틴 기반이다.
Kotlin Flow는 데이터 스트림이고, 코루틴 상에서 리액티브 프로그래밍*을 지원하기 위한 구성 요소이다.
*리액티브 프로그래밍 - 데이터가 변경 될 때 이벤트를 발생시켜서 데이터를 계속해서 전달하도록 하는 프로그래밍 방식
Flow 말 그대로 흐름이라는 개념이 중요하다.
데이터를 순차적으로 값을 내보내며 위 그림처럼 Producer에서 Consumer로 데이터가 흐른다고 보면 된다.
여기서 Producer는 데이터 로직, Consumer는 UI 로직이라고 보면 된다.
Producer는 생산자, Intermediary는 중간 연산자, Consumer는 소비자이다.
Producer에서 데이터를 발행한다. 보통은 Rest API나 Room같은 네트워크 통신이나 DB의 데이터를 가져오게 된다.
Intermediary에서는 생성한 데이터를 수정하는 단계이다. Chat GPT가 설명하는 다양한 연산자를 통해 데이터를 가공한다고 보면 된다.
Consumer는 가공한 데이터를 받아서 UI에 띄우는 등 데이터를 소비하는 단계이다.
Flow가 아직 어떤 식으로 코드를 짜는지 감이 오질 않아서 물어봤다.
Flow{} 안에서 데이터를 처리하면 filter와 map같은 연산자를 통해 데이터를 변형시켜 collect로 데이터를 소비하도록 되어있다.
LiveData VS Kotlin Flow
당연히 물어봤다.
그렇다고 한다.
Chat GPT가 자세하게 설명했으니 나는 간단하게 핵심만 짚어보겠다.
중요한것은 LiveData는 데이터를 중간에서 가공할 수 없어서(데이터 스트림이 아니기 때문에) UI의 상태 변경과 같은 간단한 데이터 처리에 적합하며,
Kotlin Flow는 데이터를 가공할 수 있고 코루틴 스케줄링과 조합해서 데이터를 지연시키거나 버퍼링(몇 초 뒤에 데이터가 바뀌도록 또는 몇초마다 데이터를 갱신하도록) 할 수 있어서 대량의 데이터를 처리할 때 적합하다.
프로젝트에서 급식표와 시간표를 가져올때 다음과 같이 방대한 데이터가 들어온다면 LiveData로는 관리하라면 할 수 있겠지만 Kotlin Flow를 사용하면 더욱 편하게 데이터를 가공하고 다듬어서 띄워줄 수 있을것 같았다.
{
"hisTimetable": [
{
"head": [
{
"list_total_count": 6
},
{
"RESULT": {
"CODE": "INFO-000",
"MESSAGE": "정상 처리되었습니다."
}
}
]
},
{
"row": [
{
"ATPT_OFCDC_SC_CODE": "T10",
"ATPT_OFCDC_SC_NM": "제주특별자치도교육청",
"SD_SCHUL_CODE": "9290076",
"SCHUL_NM": "남녕고등학교",
"AY": "2023",
"SEM": "1",
"ALL_TI_YMD": "20230330",
"DGHT_CRSE_SC_NM": "주간",
"ORD_SC_NM": "일반계",
"DDDEP_NM": "7차일반",
"GRADE": "1",
"CLRM_NM": "1-4",
"CLASS_NM": "4",
"PERIO": "1",
"ITRT_CNTNT": "정보",
"LOAD_DTM": "20230308"
},
{
"ATPT_OFCDC_SC_CODE": "T10",
"ATPT_OFCDC_SC_NM": "제주특별자치도교육청",
"SD_SCHUL_CODE": "9290076",
"SCHUL_NM": "남녕고등학교",
"AY": "2023",
"SEM": "1",
"ALL_TI_YMD": "20230330",
"DGHT_CRSE_SC_NM": "주간",
"ORD_SC_NM": "일반계",
"DDDEP_NM": "7차일반",
"GRADE": "1",
"CLRM_NM": "1-4",
"CLASS_NM": "4",
"PERIO": "2",
"ITRT_CNTNT": "한국사",
"LOAD_DTM": "20230308"
},
{
"ATPT_OFCDC_SC_CODE": "T10",
"ATPT_OFCDC_SC_NM": "제주특별자치도교육청",
"SD_SCHUL_CODE": "9290076",
"SCHUL_NM": "남녕고등학교",
"AY": "2023",
"SEM": "1",
"ALL_TI_YMD": "20230330",
"DGHT_CRSE_SC_NM": "주간",
"ORD_SC_NM": "일반계",
"DDDEP_NM": "7차일반",
"GRADE": "1",
"CLRM_NM": "1-4",
"CLASS_NM": "4",
"PERIO": "3",
"ITRT_CNTNT": "영어",
"LOAD_DTM": "20230308"
},
{
"ATPT_OFCDC_SC_CODE": "T10",
"ATPT_OFCDC_SC_NM": "제주특별자치도교육청",
"SD_SCHUL_CODE": "9290076",
"SCHUL_NM": "남녕고등학교",
"AY": "2023",
"SEM": "1",
"ALL_TI_YMD": "20230330",
"DGHT_CRSE_SC_NM": "주간",
"ORD_SC_NM": "일반계",
"DDDEP_NM": "7차일반",
"GRADE": "1",
"CLRM_NM": "1-4",
"CLASS_NM": "4",
"PERIO": "4",
"ITRT_CNTNT": "수학",
"LOAD_DTM": "20230308"
},
{
"ATPT_OFCDC_SC_CODE": "T10",
"ATPT_OFCDC_SC_NM": "제주특별자치도교육청",
"SD_SCHUL_CODE": "9290076",
"SCHUL_NM": "남녕고등학교",
"AY": "2023",
"SEM": "1",
"ALL_TI_YMD": "20230330",
"DGHT_CRSE_SC_NM": "주간",
"ORD_SC_NM": "일반계",
"DDDEP_NM": "7차일반",
"GRADE": "1",
"CLRM_NM": "1-4",
"CLASS_NM": "4",
"PERIO": "5",
"ITRT_CNTNT": "통합사회",
"LOAD_DTM": "20230308"
},
{
"ATPT_OFCDC_SC_CODE": "T10",
"ATPT_OFCDC_SC_NM": "제주특별자치도교육청",
"SD_SCHUL_CODE": "9290076",
"SCHUL_NM": "남녕고등학교",
"AY": "2023",
"SEM": "1",
"ALL_TI_YMD": "20230330",
"DGHT_CRSE_SC_NM": "주간",
"ORD_SC_NM": "일반계",
"DDDEP_NM": "7차일반",
"GRADE": "1",
"CLRM_NM": "1-4",
"CLASS_NM": "4",
"PERIO": "6",
"ITRT_CNTNT": "통합사회",
"LOAD_DTM": "20230308"
}
]
}
]
}
그래서!
호기심에 Chat GPT한테 물어봤다.
중간 코드는 길어서 생략
실제로 내가 작성한 ViewModel 코드를 들고 LiveData로 작성한 코드인데 Flow로 바꿔달라했더니 기특하게도 코드를 짜줬다.
그리고 본인이 무슨 짓을 했는지 설명까지 해줬다.
물론 저 코드는 다른 코드를 안보여줘서 좀 안맞는 부분도 있었지만 하나의 함수를 보여주고 좀 더 상세하게 어떻게 하라고 지시하니깐 완벽에 가까운 코드를 만들어냈다.
이젠 인공지능이 코딩하는 시대인데 존심이 있지 참고만 하고 시간표와 급식표는 Kotlin Flow로 변환을 했다.
아직 디자인이며 기능같은게 확실하지 않기 때문에 데이터를 가공하지는 않고 제대로 작동하는지만 띄워놨다.
매우 잘 뜬다^^
LiveData랑 Kotlin Flow 비교하는 글인데 Chat GPT얘기가 더 많은거 같지만 구글링할때나 레퍼런스 코드 참조할때 Chat GPT 활용하면 더 빠르게 코딩할 수 있을거같아서 얘기해본다.
끄읏
참고
'Android' 카테고리의 다른 글
[Android] Paging3 사용해보기 (0) | 2023.04.08 |
---|---|
[Android] Navigation Bar와 Bottom Sheet를 같이 쓸 때 문제점과 주의사항 (0) | 2023.03.24 |
[Android] Android Architecture (0) | 2023.03.03 |
[Android] 안드로이드 에러 분석 방법 및 에러 종류에 따른 설계 방법 (0) | 2023.02.19 |
[Android] REST API 예외처리 (0) | 2023.02.10 |