Foggy day

[Flutter] MethodChannel - Android 본문

Flutter/Flutter 기타

[Flutter] MethodChannel - Android

jinhan38 2023. 8. 22. 22:02

이번 포스팅에서는 MethodChannel에 대해 간략히 살펴보고, Android Native와 통신하는 방법을 알아보겠습니다. Flutter는 MethodChannel을 사용해서 각 플랫폼과 통신할 수 있습니다. 메소드 채널은 비동기방식이며 FIFO 순서를 보장합니다. 

 

 

1. Flutter -> Android Native

2. Android Native -> Flutter 

 

 

 

1. Flutter -> Android Native

먼저 볼 것은 Flutter에서 Android Native의 함수를 호출하는 방법입니다. 

 

- Flutter(Dart)

Flutter 측면에서 호출하는 방식은 간단합니다. MethodChannel 클래스를 생성하고, 생성자에 채널 이름으로 원하는 문자열을 넣습니다. 그리고 invokeMethod 함수를 호출하는데, 이때 함수명과 전달하고자 하는 데이터를 전달해 주세요. 

invokeMethod 함수는 Future<T?> 를 리턴하기 때문에 비동기적으로 처리할 수 있습니다. 결과 값은 Platform 측면에서 result.success() 함수를 사용해 전달할 수 있습니다. 

  void checkMethodChannel() {
    const MethodChannel("channelName").invokeMethod(
      "checkMethodChannel",
      {
        "data": "aaa",
      },
    ).then((value) {
      // do something
    });
  }

 

 

- Android(Kotlin)

Android 쪽에서도 많은 작업을 필요로 하지는 않습니다.

우선 FlutterActivity를 상속받은 MainActivity에서 configureFlutterEngine 함수를 구현해 주세요. 그리고 MethodChannel 클래스를 사용하는데 이 때 flutterEngine으로부터 받은 binaryMessenger를 전달해주세요. Flutter와 플랫폼 간에 MethodChannel을 사용하여 통신을 할 때 보내는 쪽에서 binary로 인코딩하고, 받는 쪽에서 디코딩을 하는 구조입니다. 

Dart 코드와 kotlin 코드에서 일치시켜야 하는 것은 channelName과 함수 name입니다. 채널이름으로 channelName이라는 문자열을 입력했고, 함수명으로는 checkMethodChannel를 사용했습니다. 이제 Dart에서 함수를 호출하면 아래 코드의 핸들러를 통해 통신할 수 있습니다. 

Dart에서 전달한 값은 call.arguments로 받아볼 수 있습니다. 또한 result.success() 함수를 이용해 리턴 값을 보내줄 수 있습니다. 

class MainActivity : FlutterActivity() {

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "channelName").setMethodCallHandler { call, result ->
            when (call.method) {
                "checkMethodChannel" -> {
                    // call.arguments
                    // result.success({value})
                    // do something
                }
            }
        }
    }

}

 

 

 

2. Android Native -> Flutter 

두 번째로 볼 것은 Native에서 Flutter의 함수를 호출하는 방법입니다. 

 

- Android(Kotlin)

Android에서 Dart로 함수를 호출하기 위해서는 1번에서와 마찬가지로 MaintActivity에서 configureFlutterEngine 함수를 구현해야 합니다. 그리고 전달받은 binaryMessenger를 사용해서 MethodChannel클래스의 invokeMethod 함수를 호출해 주세요. 이때 채널 이름과 함수 이름을 반드시 Dart의 값과 맞춰줘야 합니다. 데이터 전달을 위해서 json으로 형식으로 변환시켜 주었습니다. 

class MainActivity : FlutterActivity() {

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "channelName").invokeMethod(
            "checkResult",
            JSONObject(mapOf("result" to true)).toString(),
        )
    }

}

 

- Flutter(Dart)

main.dart 파일의 최상위 레벨에 MethodChannel 클래스를 생성하고, 생성자에 channel 이름을 전달해주세요. 그리고 main 함수에서 핸들러를 등록해 줍니다. nativeMethodCallHandler 함수에서 전달받은 MethodCall 클래스에서 method 이름과, 전달 받은 데이터인 arguments를 확인할 수 있습니다. 

const platform = MethodChannel("channelName");

void main() {
  WidgetsFlutterBinding.ensureInitialized();

  platform.setMethodCallHandler(nativeMethodCallHandler);

  runApp(const MyApp());
}

Future<dynamic> nativeMethodCallHandler(MethodCall methodCall) async {
  print('nativeMethodCallHandler methodCall : ${methodCall.method}');
  print('nativeMethodCallHandler argument : ${methodCall.arguments}');
  switch (methodCall.method) {
    case "checkResult":
      break;
  }
}