본문 바로가기
사이드프로젝트

Flutter에서 앱 아이콘 동적 변경

by project-sf 2026. 3. 26.

최근 Flutter 앱에 테마 전환 기능을 넣으면서, 테마에 맞춰 앱 아이콘도 함께 바뀌게 만들고 싶었다.
iOS에서는 비교적 자연스럽게 보였고 실제로도 구현 경로가 어느 정도 명확했다. 그런데 Android까지 같은 감각으로 붙이려다 보니, 생각보다 훨씬 많은 문제를 만나게 됐다.

이번 글은 “앱 아이콘 변경 기능을 넣으려다 왜 Android에서는 결국 빼기로 했는가”에 대한 기록이다.
결론부터 말하면, iOS는 유지하고 Android는 포기했다. 기능이 안 돼서가 아니라, 개발 복잡성과 실행 안정성, 테스트 비용이 너무 커졌기 때문이다.

시작은 단순했다

처음 의도는 간단했다.

  • classic 테마면 classic 아이콘
  • blossom 테마면 blossom 아이콘

Flutter 쪽에서는 MethodChannel로 네이티브를 호출하고,
iOS와 Android에서 각각 아이콘을 바꾸면 끝날 거라고 생각했다.

iOS는 alternate icon API가 있어서 setAlternateIconName 기반으로 접근하면 됐다.
물론 여기서도 엔진 초기화 시점, 채널 등록 시점, asset catalog 설정, Info.plistproject.pbxproj 정합성 같은 이슈가 있었지만, 적어도 “플랫폼이 제공하는 공식 흐름” 위에서 움직이고 있다는 느낌이 있었다.

문제는 Android였다.

Android는 “아이콘 변경”이 아니라 “런처 컴포넌트 교체”에 가깝다

Android에서 앱 아이콘을 바꾼다는 건 단순히 PNG 파일을 갈아끼우는 개념이 아니다.
보통 activity-alias를 여러 개 선언해두고, 그중 어떤 alias를 enable/disable 하느냐에 따라 런처에 보이는 아이콘을 바꾸는 방식으로 구현한다.

즉 구조는 이런 식이 된다.

  • MainActivity
  • ClassicAlias
  • BlossomAlias

그리고 테마가 바뀌면 alias의 활성 상태를 바꾼다.

문제는 이 방식이 런처 엔트리 자체를 건드린다는 점이다.
이게 단순 UI 변경이 아니라 앱 진입점에 영향을 주는 작업이라, 시스템과 개발 도구가 생각보다 민감하게 반응한다.

실제로 겪은 문제들

구현을 붙이고 테스트를 시작하자 바로 여러 현상이 터졌다.

1. flutter run이 앱을 못 찾는 문제

가장 먼저 만난 건 이런 종류의 에러였다.

  • Default activity not found
  • package identifier or launch activity not found
  • Activity class ... does not exist

원인은 Flutter 툴이 Android 앱을 실행할 때 launch activity를 찾는 방식에 있었다.
내 쪽 구조는 alias 중심으로 런처를 돌리고 있었는데, Flutter 툴은 이 상태를 항상 잘 이해하지 못했다.
특히 activity-alias만 런처로 존재하는 경우, 개발 중 flutter run이 APK 안에서 기본 액티비티를 제대로 읽지 못하는 상황이 생겼다.

즉 앱은 “설치된 것처럼” 보이는데, 실행은 안 되는 상태가 만들어졌다.

2. 아이콘 변경 순간 앱이 백그라운드로 내려감

이건 사용자 경험 측면에서 제일 거슬리는 문제였다.

Android에서 alias enable/disable 을 실행하면, 경우에 따라 런처 쪽 포커스가 바뀌면서 앱이 내려가거나 다시 실행되는 것처럼 보일 수 있다.
사용자 입장에서는 “테마 바꾸기”를 눌렀을 뿐인데 앱이 종료된 것처럼 느껴진다.

개발하면서 여러 시도를 했다.

  • 테마 변경 순간 바로 적용
  • onPause() 시점에 적용
  • onUserLeaveHint() 시점에 적용
  • onTrimMemory(UI_HIDDEN) 같은 더 뒤의 lifecycle 에서 적용

하지만 lifecycle 훅은 생각보다 미묘했다.
알림창만 내려도 트리거되거나, 앱이 실제로 사라지기 전에 호출되거나, 기기와 런처에 따라 체감이 달라졌다.

결국 “사용자가 불편하지 않게 아이콘을 바꾼다”는 목표 자체가 Android에서는 꽤 까다로운 과제가 됐다.

3. 홈 화면에 앱 아이콘이 두 개 보이는 문제

어떤 시점에서는 classic과 blossom 아이콘이 둘 다 런처에 나타났다.
이건 alias 활성화 로직과 디버그/릴리즈 manifest 구성이 완전히 정리되지 않았을 때 생겼다.

특히 flutter run을 살리기 위해 MainActivity에 런처를 남기고,
실제 아이콘 전환을 위해 alias도 함께 두면, 기기 입장에서는 “둘 다 런처 후보”처럼 보이게 될 수 있다.

즉 개발 편의와 앱 구조 안정성 사이에서 계속 줄다리기를 하게 된다.

4. 한 번 아이콘을 바꾼 뒤 설치 상태가 꼬이는 문제

이것도 꽤 골치 아팠다.
아이콘 변경 후 다시 실행하거나 재설치할 때 에뮬레이터/디바이스가 이전 상태를 끌고 가면서,
MainActivity 혹은 alias 경로가 꼬이는 일이 생겼다.

그 결과는 보통 다음 중 하나였다.

  • 앱 실행 실패
  • 기본 activity 탐지 실패
  • adb shell am start 실패
  • uninstall 전까지 상태가 풀리지 않음

즉 기능 자체는 “되기도 하는데”, 테스트 루프가 계속 오염됐다.
개발할 때 가장 피곤한 유형의 문제다.

iOS는 왜 상대적으로 나았나

iOS도 마냥 쉬운 건 아니었다.
AppDelegateFlutterImplicitEngineDelegate와 맞물리는 방식, MethodChannel 등록 타이밍, alternate icon asset 설정 등 조정할 부분이 꽤 있었다.

그래도 iOS는 적어도 다음이 명확했다.

  • 시스템이 alternate app icon을 공식 지원함
  • 설정 위치가 비교적 정해져 있음
  • 아이콘 전환이 런처 alias 해킹에 의존하지 않음

즉 “문제를 해결해가며 안정화할 수 있는 느낌”이 있었다.

반면 Android는 구현 자체보다, 개발 도구와 테스트 루프를 깨뜨리는 부작용이 더 크게 다가왔다.

그래서 내린 결론

결국 프로젝트에서는 이렇게 정리했다.

  • iOS: 앱 아이콘 변경 유지
  • Android: 테마만 변경하고 앱 아이콘 변경은 제외

중요한 건 “Android에서 기술적으로 불가능해서”가 아니라는 점이다.
충분히 구현 가능하다. 실제로 많은 앱이 alias 기반으로 동적 아이콘을 제공한다.

하지만 이번 프로젝트 기준으로는 다음 판단이 더 중요했다.

  • 기능 가치보다 유지 비용이 더 큼
  • 개발 중 실행 안정성이 너무 많이 깨짐
  • 디버그/릴리즈/에뮬레이터/실기기마다 확인 포인트가 늘어남
  • 사용자 입장에서 테마 변경보다 앱 튕김이나 실행 오류가 훨씬 치명적임

즉 “할 수 있느냐”보다 “지금 이 프로젝트에서 감당할 만하냐”의 문제였다.

이번 작업에서 얻은 교훈

이번 일로 몇 가지를 다시 느꼈다.

첫째, 플랫폼이 공식적으로 잘 지원하는 기능인지 먼저 봐야 한다.
같은 ‘아이콘 변경’이라도 iOS와 Android의 결이 완전히 다르다.

둘째, 개발 도구와 테스트 루프를 깨뜨리는 기능은 생각보다 비싸다.
구현 코드 몇 줄보다, 그 기능 때문에 flutter run이 흔들리는 순간 생산성이 크게 떨어진다.

셋째, 사용자 경험은 기능 존재 자체보다 안정성이 먼저다.
아이콘이 바뀌는 건 분명 멋진 기능이지만, 그 때문에 앱이 내려가거나 다시 실행되는 느낌을 주면 얻는 것보다 잃는 게 더 크다.

마지막으로, 기능을 빼는 결정도 좋은 기술 판단일 수 있다.
개발을 하다 보면 “여기까지 했는데 포기하면 아깝다”는 마음이 들기 쉽다.
그런데 실제 제품에서는 복잡성을 줄이는 선택이 더 좋은 결과를 줄 때가 많다.

이번엔 딱 그 케이스였다.
Android에서도 끝까지 밀어붙일 수는 있었겠지만, 현재 앱의 목적과 리소스를 생각했을 때는 과감히 걷어내는 쪽이 더 맞았다.

마무리

처음에는 단순한 테마 연출이라고 생각했던 기능이,
결국 플랫폼 차이와 런처 구조, 빌드 도구, lifecycle, 사용자 경험까지 한 번에 건드리는 작업이 됐다.

덕분에 꽤 많이 고생했지만, 한편으로는 “왜 어떤 기능은 플랫폼별로 다르게 결정해야 하는가”를 다시 배운 작업이기도 했다.

지금은 iOS에서만 아이콘 변경을 유지하고, Android는 더 안정적인 방향으로 정리해두었다.
아쉬움은 남지만, 제품 개발에서는 이런 선택이 오히려 더 좋은 마무리일 때가 있다.