회사에서 서비스 하던 앱 중 가장 규모가 크던 L사 택배 앱은 기존에 다른 회사에서 운영 하던 앱의 고도화 버전이다. 하지만 개발을 위해 기존 앱의 프로젝트(코드)를 받은 것이 아니라 기존 앱의 화면 및 동작, 사용 설명서 및 약간의 기획 문서를 가지고 앱을 만든 상황이였고 예정일에 프로젝트 종료는 됐으나 이런 저런 문제들이 발견되어 정식 출시(유료화)는 못 하는 상황이였다. 그 중 가장 큰 문제로는 기존 앱(구앱)에 비해 심한 배터리 소모 및 발열 문제였는데 내가 그 부분을 맡게 됐다.
먼저 배터리 소모 및 발열 문제가 일어날 수 있는 케이스가 뭐가 있는지 정보를 탐색 했고 많은 정보가 있었지만 다음과 같은 정보들을 위주로 코드를 분석 했다.
블루투스 장비 검색 이슈
서비스 컴포넌트 관련 이슈
브로드캐스트 리시버 관련 이슈
기타 사용 이슈 (날씨, 구앱 신앱 동시 사용)
메모리 문제
1. 블루투스 장비 검색
택배 앱의 경우 송장을 스캔 하기 위해 블루투스 스캐너를 사용 하는데 블루투스 연결 하기 위해 앱에서 블루투스 장치 스캔을 하고 제때 종료가 되지 않으면 메모리 누수 및 발열 문제가 일어날 수 있다. 하지만 L사 앱의 경우 앱에서 블루투스 장치 스캔을 사용 하고 있지 않았다.
2. 서비스 컴포넌트 관련 이슈
앱에서 필요 하지 않은 서비스가 계속 돌면서 작업을 하게 된다면 많은 리소스를 사용하게 될 것이고 배터리 소모 및 발열 문제가 일어날 수 있다. 하지만 L사 앱에는 Firebase Message Service(푸시) 와 블루투스 스캐너를 사용 하기 위하너 서비스를 사용 하는데 이건 구앱에서도 똑같이 사용 하는 부분이여서 문제 상황에서 제외 했다
3. 브로드캐스트 리시버 관련 이슈
브로드캐스트 리시버는 사실 배터리 소모 및 발열 문제에 큰 영향을 끼친다고 보긴 어렵지만 혹시나 하는 마음에 확인 해본 결과, 특정 시간에 유저들을 로그아웃 시켜야 되는 로직에 ACTION_TIME_TICK을 사용 하여 1분마다 시간을 체크 해서 로그아웃을 시키는 코드들이 확인 됐다 이 코드의 문제점은 1분마다 리시버를 호출해서 코드를 실행 하는 부분의 문제도 있었지만 더 큰 문제는 실제로 바코드 스캐너를 사용하며 자동으로 스마트폰 화면이 꺼져야 되는데 리시버가 1분마다 호출되면서 화면이 계속 켜져 있는 문제가 있었고 이로 인해 배터리 소모 및 발열 문제가 발생 하는 걸로 확인 됐다. 이 문제를 해결 하기 위해 브로드캐스트 리시버를 제거하고 알람 매니저로 원하는 시점에 로그아웃 코드가 실행 되도록 코드를 수정 했다.
4. 기타 사용 이슈
배터리 소모 및 발열 문제를 위해 코드를 분석 하고 수정하고 여러 관점에서 접근을 하다보니 꼭 코드 문제가 아닐 수도 있지 않을까 라는 생각이 들었다. 먼저 회사에서 만든 앱(신앱)이 개발되고 테스트를 하는 시점이 날씨가 한참 덥던 여름이였고 우리 앱이 아니더라도 이 더운 날씨에 밖에서 스마트폰을 사용 하면 당연히 발열이 생길 수 밖에 없지 않나 라는 생각을 하게 됐다. 또 하나는 구앱을 사용 하던 사용자들이 신앱을 사용할 때 아직 적응이 안 되어 있어 동시에 사용을 하는 경우들이 많다고 들었고 기존에 구앱만 사용 하던 사용자들 입장에선 구앱과 신앱을 같이 사용 하는 상황은 당연히 배터리 소모 및 발열 문제가 일어날 수 밖에 없는 구조였다. 하지만 이런 부분은 추측에 불가 했기 때문에 하나의 가능성으로 회사에 보고를 했다.
5. 메모리 문제
배터리 소모 및 발열 문제에 대해 찾아 보던 중 메모리 누수 문제가 생겼을 때도 해당 문제들이 발생될 수 있다는 정보를 확인 하고 관련 정보들을 찾아 봤다. 메모리 누수에 대해 간략하게 설명 하자면 객체에 메모리가 할당된 이후 더 이상 사용 되지 않을 때 GC(Garbage Collector)에 의해 메모리가 회수 되어야 하는데 그러지 못 하는 경우에 Memory Leak 이 발생 한다. 이러한 메모리 누수를 감지 하기 위해서는 Android Studio의 Profiler 를 사용 하거나 Leak Canary 라이브러리를 사용 해서 감지할 수 있었다. 2가지 방법을 다 사용 했지만 Profiler를 통해 메모리 누수를 찾는 방법이 좀 더 문제 해결을 위한 정보를 얻기 편했다. Profiler에서 메모리 누수를 확인 하려면 앱 실행 후 MEMORY 영역에서 클릭, Capture heap dump 를 Record 해서 내역을 확인할 수 있다.
메모리 누수를 해결한 내역을 간략하게 설명하자면
그 외에 Listener 초기화, binding 객체 초기화 등 여러 메모리 누수가 있었고 테스트를 하며 문제를 해결해 나갔다.
결론적으로 배터리 누수 및 발열 문제는 잘 해결 됐고 이번 계기로 앱을 만들 때 단순히 아키텍처나 클린 코드, 최신 기술들에만 집중 해서 코드를 작성할게 아니라 배터리 소모, 발열, 메모리 누수 등 앱에서 발생할 수 있는 여러 문제들에 대한 고민도 같이 해야겠다고 생각 했다.