
플러터(Flutter)는 기본적으로 크로스플랫폼 개발 프레임워크이지만, 플랫폼별(안드로이드, iOS) 고유 기능이나 네이티브 API(예: 센서, 배터리, 서드파티 SDK 등)와 연동이 필요할 때가 많습니다. Method Channel을 사용하면 Dart 코드와 네이티브 코드(Java/Kotlin, Swift/Objective-C) 간의 양방향 통신이 가능합니다.
Method Channel의 구조와 원리
Method Channel은 Dart(Flutter)와 각 플랫폼의 네이티브 코드 사이에 메시지를 주고받는 비동기 통신 채널입니다.
- 각 채널은 고유한 이름(String)으로 식별되며, Dart에서 메서드 호출 → 네이티브에서 처리 → 결과 반환의 구조로 동작
- 데이터는 표준 메시지 코덱(StandardMessageCodec)으로 직렬화되어 전달되며, bool, int, double, String, List, Map 등 다양한 타입을 지원
구현 방법
Flutter(Dart) 측: 채널 선언 및 메서드 호출
import 'package:flutter/services.dart';
class PlatformService {
static const platform = MethodChannel('com.example.app/channel');
Future getPlatformVersion() async {
try {
final String version = await platform.invokeMethod('getPlatformVersion');
return version;
} on PlatformException catch (e) {
return "Failed: ${e.message}";
}
}
}- MethodChannel 생성 시 채널명은 네이티브 코드와 반드시 일치해야 합니다
- invokeMethod('메서드이름', arguments)로 네이티브 메서드 호출, 결과는 Future로 반환
Android(Java/Kotlin) 측: 메서드 핸들러 구현
Kotlin 예시
class MainActivity : FlutterActivity() {
private val CHANNEL = "com.example.app/channel"
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
call, result ->
when (call.method) {
"getPlatformVersion" -> {
val version = android.os.Build.VERSION.RELEASE
result.success(version)
}
else -> result.notImplemented()
}
}
}
}setMethodCallHandler에서 메서드명 분기, 결과는 result.success/ error/ notImplemented로 반환
iOS(Swift) 측: 메서드 핸들러 구현
Swift 예시
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
let controller = window?.rootViewController as! FlutterViewController
let channel = FlutterMethodChannel(name: "com.example.app/channel", binaryMessenger: controller.binaryMessenger)
channel.setMethodCallHandler { (call: FlutterMethodCall, result: @escaping FlutterResult) in
if call.method == "getPlatformVersion" {
result(UIDevice.current.systemVersion)
} else {
result(FlutterMethodNotImplemented)
}
}
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}채널명과 메서드명이 Dart와 일치해야 하며, 결과는 result()로 반환
데이터 타입 매핑
bool, int, double, String, List, Map 등 Dart의 주요 타입은 각 네이티브 언어의 대응 타입으로 자동 변환됩니다.
예: Dart의 int → Kotlin의 Int/Long, Swift의 NSNumber, Java의 Integer/Long 등
네이티브 → Flutter 호출 (역방향)
네이티브 코드에서 invokeMethod를 사용해 Flutter로 이벤트나 데이터를 전달할 수도 있습니다.
Flutter에서는 setMethodCallHandler로 네이티브에서 오는 호출을 처리합니다.
실전 활용 팁
핵심 개발 포인트
- 채널명, 메서드명 일치: Dart와 네이티브 코드 모두 동일한 채널명/메서드명을 사용해야 합니다
- 비동기 처리: 모든 통신은 Future 기반 비동기 방식이므로, UI 블로킹 없이 안전하게 동작합니다
- 데이터 직렬화: 복잡한 데이터는 Map/List로 변환해 주고받는 것이 안전합니다
- Pigeon 패키지: 타입 안전성과 자동 코드 생성을 원한다면 Pigeon을 활용할 수 있습니다
대표 활용 예시
배터리 잔량, 센서 정보, 네이티브 SDK, 서드파티 결제, 푸시 알림, 파일 시스템 접근 등 Flutter에서 직접 지원하지 않는 플랫폼 기능 연동에 필수입니다.
배터리 정보 조회 예시
// Flutter 측
Future getBatteryLevel() async {
try {
final int result = await platform.invokeMethod('getBatteryLevel');
return result;
} on PlatformException catch (e) {
return -1;
}
}// Android 측
"getBatteryLevel" -> {
val batteryManager = getSystemService(Context.BATTERY_SERVICE) as BatteryManager
val batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
result.success(batteryLevel)
}마무리
플러터의 Method Channel을 활용하면 안드로이드(Java/Kotlin), iOS(Swift/Obj-C)의 네이티브 기능을 자유롭게 호출하고, 플랫폼별 맞춤 기능을 하나의 코드베이스에서 효율적으로 확장할 수 있습니다.
크로스플랫폼의 장점을 유지하면서도 각 플랫폼의 고유한 기능을 최대한 활용할 수 있는 Method Channel을 통해 더욱 완성도 높은 Flutter 앱을 개발해보세요.
'IT기술 > 플러터 (flutter)' 카테고리의 다른 글
| Flutter 패키지 & 플러그인 개발 완벽 가이드: 코드 재사용성 극대화하기 (4) | 2025.07.17 |
|---|---|
| Flutter 접근성(Accessibility) 완벽 가이드: 모든 사용자를 위한 포용적 앱 개발 (4) | 2025.07.16 |
| Flutter 앱 스토어 배포 완벽 가이드: 구글 플레이스토어 & 애플 앱스토어 등록 방법 (8) | 2025.07.13 |
| Flutter 테스트 완벽 가이드: 단위/위젯/통합 테스트로 앱 품질 극대화하기 (0) | 2025.07.12 |
| Flutter 애니메이션 완벽 가이드: 기본부터 고급 활용법까지 (4) | 2025.07.11 |