[Flutter] Method Channel vs Event Channel

Chanceยท2024๋…„ 11์›” 19์ผ

Flutter์˜ Event Channel๊ณผ Method Channel ์†Œ๊ฐœ

Flutter๋Š” Google์ด ๊ฐœ๋ฐœํ•œ UI ํˆดํ‚ท์œผ๋กœ, ๋‹จ์ผ ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ ๋ชจ๋ฐ”์ผ, ์›น, ๋ฐ์Šคํฌํ†ฑ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋„ค์ดํ‹ฐ๋ธŒ๋กœ ์ปดํŒŒ์ผํ•˜์—ฌ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Dart ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” Flutter๋Š” ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ์™€ ์ƒํ˜ธ์ž‘์šฉํ•˜๊ธฐ ์œ„ํ•ด Event Channel๊ณผ Method Channel์ด๋ผ๋Š” ๋‘ ๊ฐ€์ง€ ์ฃผ์š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด ์ฑ„๋„๋“ค์€ Flutter ์•ฑ๊ณผ ํ”Œ๋žซํผ๋ณ„ ์ฝ”๋“œ๋ฅผ ์—ฐ๊ฒฐํ•ด ๋„ค์ดํ‹ฐ๋ธŒ ๊ธฐ๋Šฅ์„ ์›ํ™œํžˆ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.


๊ฐœ์š”

๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ์™€์˜ ์ƒํ˜ธ์ž‘์šฉ

๋ชจ๋ฐ”์ผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์—์„œ๋Š” ํ”Œ๋žซํผ๋ณ„ API๋‚˜ ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ข…์ข… ์žˆ์Šต๋‹ˆ๋‹ค. Flutter์˜ Event Channel๊ณผ Method Channel์€ ์ด๋Ÿฌํ•œ ํ•„์š”๋ฅผ ์ถฉ์กฑํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ•๋ ฅํ•œ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด Flutter ์•ฑ์—์„œ ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ฉํ•˜์—ฌ ๋” ๊ฐ•๋ ฅํ•˜๊ณ  ์œ ์—ฐํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


Method Channel์ด๋ž€?

Method Channel์€ Flutter์™€ ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ ๊ฐ„์˜ ํ†ต์‹ ์„ ์œ„ํ•ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด Dart์—์„œ ๋„ค์ดํ‹ฐ๋ธŒ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฃผ๋กœ ํ•œ ๋ฒˆ์˜ ์š”์ฒญ๊ณผ ์‘๋‹ต์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Flutter ์•ฑ์ด ํŠน์ • ๊ธฐ๋Šฅ์„ ํ˜ธ์ถœํ•˜๊ณ  ์‘๋‹ต์„ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

Event Channel์ด๋ž€?

Event Channel์€ ์ง€์†์ ์ธ ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋„ค์ดํ‹ฐ๋ธŒ ์ธก์—์„œ Flutter๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ŠคํŠธ๋ฆผ ํ˜•์‹์œผ๋กœ ์ „์†กํ•  ์ˆ˜ ์žˆ๋Š” ํ†ต์‹  ํŒจํ„ด์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์„ผ์„œ ๋ฐ์ดํ„ฐ๋‚˜ ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ ์ƒํƒœ์™€ ๊ฐ™์ด ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ˆ˜์‹ ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.


Method Channel๊ณผ Event Channel์˜ ํ•„์š”์„ฑ

Flutter์™€ ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ ๊ฐ„์˜ ๊ฐ„๊ทน ํ•ด์†Œ

Flutter๋Š” ๊ด‘๋ฒ”์œ„ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์ง€๋งŒ, ํŠน์ • ๊ธฐ๋Šฅ์€ ๋„ค์ดํ‹ฐ๋ธŒ API๋ฅผ ํ†ตํ•ด ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ๋” ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์„ผ์„œ ๋ฐ์ดํ„ฐ ์ ‘๊ทผ, ์นด๋ฉ”๋ผ, ๋ฐฐํ„ฐ๋ฆฌ ์ƒํƒœ ํ™•์ธ ๋˜๋Š” ํ”Œ๋žซํผ๋ณ„ ์„œ๋น„์Šค๋ฅผ ํ†ตํ•ฉํ•˜๋Š” ์ž‘์—…์ด ์ด์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค. Method Channel๊ณผ Event Channel์€ ์ด๋Ÿฌํ•œ ์ƒํ˜ธ์ž‘์šฉ์„ ์œ„ํ•œ ๋‹ค๋ฆฌ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.


ํšจ์œจ์ ์ธ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ

Method Channel์€ ํ•œ ๋ฒˆ์˜ ์š”์ฒญ๊ณผ ์‘๋‹ต์ด ํ•„์š”ํ•œ ์ž‘์—…์— ์ตœ์ ํ™”๋˜์–ด ์žˆ์–ด ๋น ๋ฅด๊ณ  ํšจ์œจ์ ์œผ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
Event Channel์€ ์ง€์†์ ์ธ ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์— ์ ํ•ฉํ•˜๋ฉฐ, Flutter ์•ฑ ๋‚ด์—์„œ ์‹ค์‹œ๊ฐ„ ์—…๋ฐ์ดํŠธ์™€ ์•Œ๋ฆผ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.


Method Channel ๊ตฌํ˜„ ์˜ˆ์ œ

Flutter ์ฝ”๋“œ

๋จผ์ €, Flutter์—์„œ Method Channel์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

import 'package:flutter/services.dart';

class MethodChannelExample {
  static const platform = MethodChannel('com.example.methodchannel/sample');

  Future<void> callNativeMethod() async {
    try {
      final int result = await platform.invokeMethod('getNativeData');
      print("Result from native: $result");
    } on PlatformException catch (e) {
      print("Failed to get data: '${e.message}'");
    }
  }
}

Android ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ (Kotlin)

๋‹ค์Œ์œผ๋กœ, ๋„ค์ดํ‹ฐ๋ธŒ Android ์ฝ”๋“œ์—์„œ ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

package com.example.methodchannel

import io.flutter.embedding.android.FlutterActivity
import io.flutter.plugin.common.MethodChannel

class MainActivity: FlutterActivity() {
    private val CHANNEL = "com.example.methodchannel/sample"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
            call, result ->
            if (call.method == "getNativeData") {
                val nativeData = getNativeData()
                if (nativeData != null) {
                    result.success(nativeData)
                } else {
                    result.error("UNAVAILABLE", "Native data not available.", null)
                }
            } else {
                result.notImplemented()
            }
        }
    }

    private fun getNativeData(): Int {
        // ๋„ค์ดํ‹ฐ๋ธŒ ๋ฐ์ดํ„ฐ ๋กœ์ง
        return 42
    }
}

Event Channel ๊ตฌํ˜„ ์˜ˆ์ œ

Flutter ์ฝ”๋“œ

Event Channel์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฆฌ์Šค๋„ˆ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

import 'package:flutter/services.dart';

class EventChannelExample {
  static const EventChannel eventChannel = EventChannel('com.example.eventchannel/sample');

  void startListening() {
    eventChannel.receiveBroadcastStream().listen((dynamic event) {
      print("Event from native: $event");
    }, onError: (dynamic error) {
      print("Error: $error");
    });
  }
}

Android ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ (Kotlin)

Android์—์„œ Event Channel์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

package com.example.eventchannel

import io.flutter.embedding.android.FlutterActivity
import io.flutter.plugin.common.EventChannel
import java.util.*

class MainActivity: FlutterActivity() {
    private val CHANNEL = "com.example.eventchannel/sample"
    private var events: EventChannel.EventSink? = null

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        EventChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setStreamHandler(
            object : EventChannel.StreamHandler {
                override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
                    this@MainActivity.events = events
                    startSendingEvents()
                }

                override fun onCancel(arguments: Any?) {
                    this@MainActivity.events = null
                }
            }
        )
    }

    private fun startSendingEvents() {
        // ์ด๋ฒคํŠธ๋ฅผ ์ฃผ๊ธฐ์ ์œผ๋กœ ์ „์†ก
        Timer().scheduleAtFixedRate(object : TimerTask() {
            override fun run() {
                events?.success("Event data from native")
            }
        }, 0, 1000)
    }
}

์ฃผ์š” ์‚ฌ์šฉ ์‚ฌ๋ก€

Method Channel์˜ ์‚ฌ์šฉ ์‚ฌ๋ก€

๋””๋ฐ”์ด์Šค ์ •๋ณด: ๋ฐฐํ„ฐ๋ฆฌ ์ˆ˜์ค€, ์‹œ์Šคํ…œ ๋ฒ„์ „๊ณผ ๊ฐ™์€ ๋””๋ฐ”์ด์Šค ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ.
๋‹จ๋ฐœ์„ฑ ์„ค์ •: ํ•œ ๋ฒˆ์˜ ํ˜ธ์ถœ๊ณผ ์‘๋‹ต์ด ํ•„์š”ํ•œ ์„ค์ • ์ž‘์—….
๋„ค์ดํ‹ฐ๋ธŒ UI ์ปดํฌ๋„ŒํŠธ: ๋„ค์ดํ‹ฐ๋ธŒ ๋‹ค์ด์–ผ๋กœ๊ทธ ๋˜๋Š” ์•Œ๋ฆผ๊ณผ ๊ฐ™์€ UI ์š”์†Œ์™€ ์ƒํ˜ธ์ž‘์šฉ.

Event Channel์˜ ์‚ฌ์šฉ ์‚ฌ๋ก€

์„ผ์„œ ๋ฐ์ดํ„ฐ: ๊ฐ€์†๋„๊ณ„, ์ž์ด๋กœ์Šค์ฝ”ํ”„ ๋“ฑ ๋””๋ฐ”์ด์Šค ์„ผ์„œ์—์„œ ์‹ค์‹œ๊ฐ„ ์—…๋ฐ์ดํŠธ ์ˆ˜์‹ .
์‹ค์‹œ๊ฐ„ ์•Œ๋ฆผ: ๋„ค์ดํ‹ฐ๋ธŒ ์„œ๋น„์Šค์—์„œ ์‹ค์‹œ๊ฐ„ ์—…๋ฐ์ดํŠธ ๋˜๋Š” ์•Œ๋ฆผ ์ˆ˜์‹ .
์œ„์น˜ ์—…๋ฐ์ดํŠธ: ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ง€์†์ ์ธ ์œ„์น˜ ๋ณ€๊ฒฝ ์ถ”์ .

๊ฒฐ๋ก 

Flutter์˜ Method Channel๊ณผ Event Channel์€ ๋„ค์ดํ‹ฐ๋ธŒ ํ”Œ๋žซํผ ๊ธฐ๋Šฅ๊ณผ์˜ ํ†ตํ•ฉ์„ ์œ„ํ•œ ํ•„์ˆ˜ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ์ด๋“ค์„ ํ™œ์šฉํ•˜๋ฉด Flutter ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•˜๊ณ  ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Method Channel์€ ๋‹จ๋ฐœ์„ฑ ์ž‘์—…์—, Event Channel์€ ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ ์ฒ˜๋ฆฌ์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ฑ„๋„์„ ํšจ๊ณผ์ ์œผ๋กœ ๊ตฌํ˜„ํ•˜๋ฉด ๋”์šฑ ๊ฐ•๋ ฅํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : https://blog.stackademic.com/understanding-event-channel-and-method-channel-in-flutter-and-dart-9134d6a8ceba

0๊ฐœ์˜ ๋Œ“๊ธ€