Flutter에서 네이티브 모듈 연동 시 Method Channel 이슈

문제 상황

기존 Android 네이티브로 구현된 커스텀 카메라 모듈을 Flutter 앱에 통합해야 했다. 기본 image_picker 패키지로는 요구사항을 충족할 수 없어서 직접 Method Channel을 구성했다.

static const platform = MethodChannel('com.example/camera');

Future<String?> captureImage() async {
  try {
    final String? result = await platform.invokeMethod('captureImage');
    return result;
  } catch (e) {
    print('Error: $e');
    return null;
  }
}

문제는 간헐적으로 result가 null로 반환된다는 점이었다. 로그를 보니 네이티브 측에서는 정상적으로 파일 경로를 반환하는데, Dart 측에서 받지 못하는 상황이었다.

원인 분석

Android 네이티브 코드를 살펴봤더니 카메라 캡처 후 파일 저장이 백그라운드 스레드에서 처리되고 있었다. Method Channel의 result.success()를 메인 스레드가 아닌 곳에서 호출하면 Flutter 엔진과의 통신에 문제가 생길 수 있다.

// 문제가 있던 코드
Thread {
    val filePath = saveImageToFile(bitmap)
    result.success(filePath) // 백그라운드 스레드에서 호출
}.start()

해결

Handler를 사용해 메인 스레드에서 result를 반환하도록 수정했다.

Thread {
    val filePath = saveImageToFile(bitmap)
    Handler(Looper.getMainLooper()).post {
        result.success(filePath)
    }
}.start()

이후 null 반환 문제가 완전히 해결됐다. Method Channel 사용 시 result 콜백은 반드시 메인 스레드에서 호출해야 한다는 점을 다시 확인했다.

추가 개선

에러 핸들링도 강화했다. 네이티브 측에서 예외 발생 시 적절한 에러 코드와 메시지를 전달하도록 했다.

try {
    // 처리 로직
} catch (e: Exception) {
    Handler(Looper.getMainLooper()).post {
        result.error("CAPTURE_FAILED", e.message, null)
    }
}

Flutter와 네이티브 코드 간 통신은 단순해 보여도 스레드 모델과 비동기 처리에 주의가 필요하다.