-
Android : 번들 관리의 중요성.... java.lang.RuntimeException:android.os.TransactionTooLargeExceptionAndroid📱/삽질 기록... 2024. 2. 9. 20:28
이번 프로젝트를 하면서 너무 당연한 건데 생각지도 못했던 문제를 발견하였다.
A화면에서 서버를 통해 데이터를 받아서 B화면에 arguments로 데이터를 전달해서 사용하는 로직이 있었는데
이번에 외부회사 정책 때문에 정책이 변경되면서 B화면에서 브라우저를 갔다 와야 하는 상황이 발생하였다.
그래서 브라우저를 켰는데 앱이 백그라운드로 넘어가는 순간 os에서 java.lang.RuntimeException:android.os.TransactionTooLargeException를 뱉으며 앱을 죽이는 현상을 발견하였다.
이를 발견하고 메세지를 읽어보니 뭔가 너무 큰 데이터를 저장하려고 해서 중지했다는 문제를 인식하였고, 앱이 백그라운드로 넘어갈 때 현재 앱의 상태를 번들로 onSaveInstanceState를 할 때 용량이 너무 커서 죽이는 거 같다는 가설을 새우고 버그를 재현해 보기 위해서 해당 화면으로 이동하여 홈 버튼을 눌러 앱을 백그라운드로 보냈더니 같은 에러를 뱉으며 종료하는 것을 확인하였다.
주고받는 데이터 중 경로 데이터가 있는데, 내가 테스트하려고 선택한 경로가 너무 멀어서 데이터가 커져 일어나는 에러로 판단할 수 있었고,
수정을 하기 위해서 argument의 데이터를 받아서 사용 후 clear()를 해주는 식으로 문제를 해결해 보려고 시도하였다.
하지만 대실패...
문제의 원인을 다시 살펴보다가 argument로 너무 큰 데이터를 전달하려는 시도 자체가 문제인거 같다는 생각이 들었다.
clear만으로는 뭔가 데이터가 다 지워지지 않는 거 같은느낌?
먼저 기존에 경로를 보내던 bundle에 출발지, 도착지만 보내도록 수정해 보았는데
홈 버튼을 눌러도 에러가 나지 않는 것을 체크하였다.
데이터를 전달할 때는 용량이 괜찮다가 onSaveInstanceState에서 fragment의 argument를 저장하려 하면 데이터가 초과하는 것을 보였다.
그래서 경로를 argument로 전달하지 않고, B화면에서 API 요청을 보내도록 대공사 시작....
기존 API 요청 로직을 B화면이 왔을 때 요청하도록 수정하고, 번들로는 출발지, 도착지 정보만 넘기도록 수정하였다.
그리고 테스트해보니 에러가 해결되었다!
bundle은 너무 많은 데이터를 전달하면 안 되는데
서비스가 확장되면서 넘겨줄 데이터가 많아지는 것을 계산하지 못했던 거 같다.
bundle의 용량제한은 1MB로 argument를 이용하거나 많은 데이터를 전달해야 하는 상황이면 주의가 필요할 거 같다.
현재 사용 중인 번들의 크기가 궁금하면
val parcel = Parcel.obtain() parcel.writeValue(bundle) val byte = parcel.marshall() parcel.recycle() Timber.d("arguments : ${byte.size}")
이 코드로 확인이 가능하다
'Android📱 > 삽질 기록...' 카테고리의 다른 글
[Android] setFragmentResultListener() 삽질 기록 (0) 2024.04.20 [Android] Gson LinkedTreeMap cast 에러 해결 (1) 2024.04.19 [Android] Camera Preview가 준비됐는지 알아보기 (0) 2024.02.08 [Android] isMinifyEnabled 사용 시 java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType 에러 (0) 2023.09.15 [Android] 화면 이동시 cannot be found from the current destination (0) 2023.08.28