← 전체 글로 돌아가기

Flutter

Flutter 에뮬레이터에서는 되는데 실기기에서는 안 될 때

Flutter 개발할 때 에뮬레이터와 실기기에서 다르게 동작하는 문제를 디버깅하는 방법을 정리했다.

Flutter를 개발할 때 에뮬레이터에서는 완벽하게 작동하지만, 실제 휴대폰에서 테스트하면 갑자기 동작 안 하는 경우가 있다. 보통 네트워크, 권한, 또는 빌드 모드 차이 때문이다.

먼저 확인할 것: 빌드 모드

# 에뮬레이터에서 실행 (기본은 debug 모드)
flutter run

# 실기기에서는 release 모드로 테스트해야 한다
flutter run --release

Debug 모드와 Release 모드는 많이 다르다:

  • Debug: Hot reload 지원, 모든 디버그 정보 포함, 느림
  • Release: 최적화됨, 디버그 정보 제거, 빠름, 보안 강화

API 호출이나 데이터베이스 처리가 실기기에서만 다르게 작동한다면, Release 모드에서 테스트해본다.

네트워크 설정 확인

# 에뮬레이터는 호스트의 localhost로 API에 접근할 수 있다
# 하지만 실기기는 할 수 없다

// ❌ 실기기에서는 작동하지 않음
final url = 'http://localhost:8000/api';

// ✅ 실기기에서 작동
final url = 'http://192.168.1.100:8000/api';

API 주소를 설정에서 읽도록 하면 환경마다 다르게 설정할 수 있다:

class Config {
  static const String apiUrl = String.fromEnvironment(
    'API_URL',
    defaultValue: 'http://192.168.1.100:8000/api',
  );
}

// 빌드할 때
// flutter run --dart-define=API_URL=http://192.168.1.100:8000/api

실기기 권한 확인

# 연결된 실기기 확인
flutter devices

# 로그를 보면서 실행
flutter run --device-id <device-id> -v 2>&1 | tee run.log

Android/iOS 권한이 다를 수 있다:

  • 카메라: 실기기는 사용자 승인 필요
  • 위치: 정확도가 다름 (에뮬레이터는 고정값)
  • 파일 접근: 실기기는 권한이 엄격함

권한 요청 로직을 추가한다:

import 'package:permission_handler/permission_handler.dart';

if (await Permission.location.isDenied) {
  await Permission.location.request();
}

연결 문제 확인

# USB 디버깅이 켜져 있는지 확인
adb devices  # 실기기가 보여야 함

# WiFi로 연결된 경우
adb connect <device-ip>:5555

# 로그 확인
adb logcat | grep Flutter

에뮬레이터는 항상 리셋할 수 있지만, 실기기는 상태가 유지된다. 이전 설치본이 문제를 일으킬 수 있다:

# 설치된 앱 확인
adb shell pm list packages | grep com.example

# 완전히 제거하고 다시 설치
adb uninstall com.example.app
flutter run

성능 차이 보기

# Dart DevTools로 프로파일링
flutter pub global activate devtools
devtools

# 또는 터미널에서
flutter run --profile

Profile 모드는 Release만큼 빠르지만 일부 디버그 정보도 포함한다. 실기기에서 느려 보인다면 프로파일링으로 병목을 찾는다.

최종 확인 체크리스트

  1. Release 모드로 테스트했는가
  2. API 주소가 실기기에서 접근 가능한가
  3. 필요한 권한이 모두 승인되었는가
  4. 앱을 완전히 제거하고 새로 설치했는가
  5. 네트워크가 에뮬레이터와 같은가 (VPN, Proxy 등)

These checks usually resolve the discrepancies between emulator and real device behavior.