MethodChannel과 다르게 네이티브에서 단순 스트링만 전달하고 싶다면 BasicMessageChannel을 사용하면 된다.
안드로이드
플러터에서 보내는 메세지를 받을 수 있다.
(플러터에서 메세지를 받는 것과 보내는 것은 아래쪽에 있다.)
보낼 때는 아래와 같이 한다. 액티비티가 보여질때(onResume) 메세지를 보낸다.
package com.example.flutter_life_cycle
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.BasicMessageChannel
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.StringCodec
class MainActivity: FlutterActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
// MethodChannel
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "example.channel/test").setMethodCallHandler {
call, result ->
if (call.method == "test") {
result.success("안드로이드 MethodChannel OK")
}
}
// basicMessageChannel
val basicMessageChannel = BasicMessageChannel<String>(
flutterEngine.dartExecutor,
"example.channel/test",
StringCodec.INSTANCE
)
basicMessageChannel.setMessageHandler { message, reply ->
reply.reply("안드로이드 basicMessageChannel 응답 $message")
}
}
override fun onResume() {
super.onResume()
val basicMessageChannel = BasicMessageChannel<String>(
flutterEngine!!.dartExecutor.binaryMessenger,
"example.channel/test",
StringCodec.INSTANCE
)
basicMessageChannel.send("onResume")
}
}
IOS
AppDelegate.swift 에 통신할 채널을 생성한다.
메세지를 전달할 부분에 사용하면 된다. 앱을 resume 시킬 때 메세지를 던지도록 하였다.
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
var basicMessageChannel: FlutterBasicMessageChannel! // BasicMessageChannel 선언
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
// FlutterViewController
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
// BasicMessageChannel 세팅
basicMessageChannel = FlutterBasicMessageChannel(
name: "example.channel/test",
binaryMessenger: controller.binaryMessenger,
codec: FlutterStringCodec.sharedInstance()
)
// MethodChannel 세팅
let methodChannel = FlutterMethodChannel(name: "example.channel/test", binaryMessenger: controller.binaryMessenger)
methodChannel.setMethodCallHandler { [weak self] (call, result) in
if call.method == "test" {
// 통신
result("OK")
} else {
result(FlutterMethodNotImplemented)
}
}
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
// 앱 종료
override func applicationWillTerminate(_ application: UIApplication) {
basicMessageChannel.sendMessage("applicationWillTerminate")
}
// 포그라운드
override func applicationWillEnterForeground(_ application: UIApplication) {
basicMessageChannel.sendMessage("applicationWillEnterForeground");
}
// 백그라운드
override func applicationDidEnterBackground(_ application: UIApplication) {
basicMessageChannel.sendMessage("applicationDidEnterBackground")
}
}
플러터
BasicMessageChannel을 선언해주고 setMessageHandler함수를 통해 이벤트 처리를 한다.
메세지를 받을 수도 있고 보낼 수도 있다.
import 'dart:developer';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
final Dio dio = Dio();
final BasicMessageChannel<String> basicMessageChannel = const BasicMessageChannel<String>("example.channel/test", StringCodec()); // BasicMessageChannel
final MethodChannel methodChannel = const MethodChannel("example.channel/test"); // MethodChannel
@override
void initState() {
// basicMessageChannel 수신
basicMessageChannel.setMessageHandler((message) async {
log("message: $message");
switch (message) {
// do something..
}
return message!;
});
// 앱 상태 감지 등록
// WidgetsBinding.instance.addObserver(this);
super.initState();
}
@override
void dispose() {
//앱 상태 감지 해제
// WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
// 앱 상태에 따른 분기처리
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
log("state: $state");
switch (state) {
case AppLifecycleState.resumed: // 포그라운드 상태
log("AppLifecycleState resumed");
break;
case AppLifecycleState.inactive: // 비활성화 상태 -> 이후 paused 발생
log("AppLifecycleState inactive");
break;
case AppLifecycleState.paused: // 백그라운드 상태
log("AppLifecycleState paused");
break;
case AppLifecycleState.detached: // 종료
log("AppLifecycleState detached");
break;
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
// methodChannel 통신
methodChannel.invokeMethod("test").then((value) {
String result = value.toString();
log("result: $result");
});
},
child: Text("methodChannel")
),
ElevatedButton(
onPressed: () async {
// basicMessageChannel 통신
await basicMessageChannel.send('Hello from Dart').then((value) {
log("value: $value");
});
},
child: Text("basicMessageChannel")
),
],
),
),
);
}
}
'dev > flutter' 카테고리의 다른 글
플러터에서 네이티브 앱 생명주기 감지 (0) | 2023.06.10 |
---|---|
플러터 리스트 또는 ListView 위젯 뒤집기 (0) | 2023.06.09 |
플랫폼 통신 MethodChannel (안드로이드, IOS) (0) | 2023.05.31 |
플러터 앱 생명주기 감지 LifeCycle (0) | 2023.05.31 |
SliverAppBar 높이 파악하기 (RenderObject) (0) | 2023.05.19 |