6 4 月 2026, 周一

一般的Flutter与原生平台的通信方式有3种:

  1. MethodChannel:主要用于Flutter端和原生端之间的方法调用 【常用】
  2. EventChannel:用于数据流的持续通信,收到消息后无法立即回复本次通信消息,通常用在原生平台主动向Flutter发送消息的场
  3. BasicMessageChannel:用于传递字符串或半结构体的数据

平台端与Flutter端之间的数据类型映射表

Dart Java Kotlin OC Swift
null null null nil (NSNull when nested) nil
bool java.lang.Boolean Boolean NSNumber numberWithBool: NSNumber(value: Bool)
int java.lang.Integer Int NSNumber numberWithInt: NSNumber(value: Int32)
int, if 32 bits not enough java.lang.Long Long NSNumber numberWithLong: NSNumber(value: Int)
double java.lang.Double Double NSNumber numberWithDouble: NSNumber(value: Double)
String java.lang.String String NSString String
Uint8List byte[] ByteArray FlutterStandardTypedData typedDataWithBytes: FlutterStandardTypedData(bytes: Data)
Int32List int[] IntArray FlutterStandardTypedData typedDataWithInt32: FlutterStandardTypedData(int32: Data)
Int64List long[] LongArray FlutterStandardTypedData typedDataWithInt64: FlutterStandardTypedData(int64: Data)
Float64List double[] DoubleArray FlutterStandardTypedData typedDataWithFloat64: FlutterStandardTypedData(float64: Data)
List java.util.ArrayList List NSArray Array
Map java.util.HashMap HashMap NSDictionary Dictionary

MethodChannel 示例代码

Flutter端代码:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class NativeCall{

  static const _channelName  = 'xyz.bczl/test';
  // 创建通道,并设置名称作为唯一标识
  static const  _platform = const MethodChannel(_channelName);

  static Future<void> sdkVersion() async {
    try {
      final int result = await _platform.invokeMethod('getSDKVersion');
      debugPrint('sdkVersion=$result');
    } on PlatformException catch (e) {
      debugPrint("Failed to get sdkVersion: '${e.message}'.");
    }
  }

  static Future<void> toast(String text) async {
    try {
      await _platform.invokeMethod('toast',{"text":text});
    } on PlatformException catch (e) {
      debugPrint(e.message);
    }
  }
}

Android端代码:

public class MainActivity extends FlutterActivity {
    private static final String CHANNEL = "xyz.bczl/test";

    @Override
    public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
        super.configureFlutterEngine(flutterEngine);
        new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
            .setMethodCallHandler(new MethodChannel.MethodCallHandler() {
                 @Override
                 public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
                     if(call.method.equals("getSDKVersion")){
                         // 返回SDK版本号
                         result.success(Build.VERSION.SDK_INT);
                     } else if(call.method.equals("toast")){
                         String text = call.argument("text");
                         // 弹出Toast
                         Toast.makeText(MainActivity.this,text,Toast.LENGTH_SHORT).show();
                         result.success(null);
                     }
                 }
            });
    }
}

EventChannel 示例代码

Flutter端,NativeCall中添加如下代码

static const _eventChannel = const EventChannel("xyz.bczl/event");

  StreamSubscription _subscription;
  void onEvent(){
    _subscription = _eventChannel
        .receiveBroadcastStream()
        .listen(
            (event) {
              debugPrint("from native event:$event");
            },
            onError: (e){
              PlatformException exception = e;
              debugPrint(exception.message);
            });
  }

  void cancel(){
    _subscription.cancel();
  }

Android端代码:

public class MainActivity extends FlutterActivity {
    EventChannel.EventSink mEvents;

    @Override
    public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
        super.configureFlutterEngine(flutterEngine);

        // 创建 EventChannel
        new EventChannel(flutterEngine.getDartExecutor().getBinaryMessenger(),"xyz.bczl/event")
        .setStreamHandler(new EventChannel.StreamHandler() {
            @Override
            public void onListen(Object arguments, EventChannel.EventSink events) {
                mEvents = events;
            }

            @Override
            public void onCancel(Object arguments) {}
        });
    }


    @Override
    protected void onPause() {
        super.onPause();
        if (mEvents != null) mEvents.success("onPause");
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mEvents != null) mEvents.success("onResume");
    }
}

小结:

  • 应在原生平台的主线程中调用通道相关的方法
  • 编写调试原生混合代码是不能热更新的,请确保App重新编译、打包、安装
  • Flutter 1.12 版本后官方更新了插件API,但是旧的接口目前依旧兼容。注意,新的版本中,是通过实现FlutterActivity的configureFlutterEngine方法创建通道,旧版处理如下:
public class MainActivity extends FlutterActivity {
    private static final String CHANNEL = "xyz.bczl/test";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
                new MethodCallHandler() {
                    @Override
                    public void onMethodCall(MethodCall call, Result result) {}
                });
    }
}
Avatar photo

sion932