Dart 语言 Dart 中的 Flutter 与 Native 代码交互方法

Dart阿木 发布于 2025-06-19 3 次阅读


Flutter 与 Native 代码交互方法详解

在Flutter开发中,与原生代码的交互是一个常见的需求。Flutter本身是一个跨平台的UI框架,但有时我们需要调用原生代码来实现一些特定的功能,比如访问设备硬件、使用第三方库等。本文将详细介绍Flutter与Native代码交互的几种方法。

1. 简介

Flutter与Native代码交互主要有以下几种方式:

1. 平台通道(Platform Channels):通过消息传递的方式在Flutter和原生代码之间进行交互。

2. 插件(Plugins):使用Dart代码封装原生代码,通过平台通道与Flutter交互。

3. Dart FFI(Foreign Function Interface):直接调用原生代码,适用于对性能要求较高的场景。

2. 平台通道

平台通道是Flutter与Native代码交互最常用的方式。它允许Flutter代码发送消息到原生代码,并接收响应。

2.1 创建平台通道

在Flutter代码中创建一个平台通道:

dart

import 'package:flutter/services.dart';

const platform = MethodChannel('com.example.app.channel');

Future<String> getPlatformVersion() async {


final String version = await platform.invokeMethod('getPlatformVersion');


return version;


}


2.2 原生代码实现

在原生代码中,你需要创建一个对应的Java或Kotlin类来接收消息:

java

import io.flutter.embedding.engine.FlutterEngine;


import io.flutter.plugin.common.MethodChannel;

public class MyPlugin implements MethodChannel.MethodCallHandler {


private final MethodChannel channel;

public MyPlugin(FlutterEngine flutterEngine) {


channel = new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), "com.example.app.channel");


channel.setMethodCallHandler(this);


}

@Override


public void onMethodCall(MethodCall call, MethodChannel.Result result) {


if (call.method.equals("getPlatformVersion")) {


result.success("Android " + android.os.Build.VERSION.RELEASE);


} else {


result.notImplemented();


}


}


}


2.3 使用平台通道

在Flutter代码中,你可以调用原生代码返回的结果:

dart

void main() {


runApp(MyApp());


}

class MyApp extends StatelessWidget {


@override


Widget build(BuildContext context) {


return MaterialApp(


home: Scaffold(


appBar: AppBar(


title: Text('Platform Channels Example'),


),


body: Center(


child: FutureBuilder<String>(


future: getPlatformVersion(),


builder: (context, snapshot) {


if (snapshot.connectionState == ConnectionState.waiting) {


return CircularProgressIndicator();


} else if (snapshot.hasError) {


return Text('Error: ${snapshot.error}');


} else {


return Text('Android ${snapshot.data}');


}


},


),


),


),


);


}


}


3. 插件

插件是另一种在Flutter中与Native代码交互的方式。它允许你使用Dart代码封装原生代码,并通过平台通道与Flutter交互。

3.1 创建插件

创建一个插件项目,并在`android/app/src/main/`目录下创建一个Java类:

java

import io.flutter.embedding.engine.FlutterEngine;


import io.flutter.plugin.common.MethodChannel;

public class MyPlugin implements MethodChannel.MethodCallHandler {


private final MethodChannel channel;

public MyPlugin(FlutterEngine flutterEngine) {


channel = new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), "com.example.app.plugin");


channel.setMethodCallHandler(this);


}

@Override


public void onMethodCall(MethodCall call, MethodChannel.Result result) {


if (call.method.equals("getPlatformVersion")) {


result.success("Android " + android.os.Build.VERSION.RELEASE);


} else {


result.notImplemented();


}


}


}


然后,在`android/app/build.gradle`文件中添加插件依赖:

gradle

dependencies {


implementation 'io.flutter:flutter_embedding_api:2.0.6'


// ... 其他依赖


}


3.2 使用插件

在Flutter代码中,你可以像使用平台通道一样使用插件:

dart

import 'package:flutter/services.dart';

const platform = MethodChannel('com.example.app.plugin');

Future<String> getPlatformVersion() async {


final String version = await platform.invokeMethod('getPlatformVersion');


return version;


}


4. Dart FFI

Dart FFI允许你直接调用原生代码,适用于对性能要求较高的场景。

4.1 创建FFI库

创建一个FFI库,并在`android/app/src/main/`目录下创建一个C/C++文件:

c

include <jni.h>


include <string.h>

JNIEXPORT jstring JNICALL


Java_com_example_app_MainActivity_getPlatformVersion(JNIEnv env, jobject thiz) {


return (env)->NewStringUTF(env, "Android " JNI_GetVersion());


}


然后,在`android/app/build.gradle`文件中添加FFI库依赖:

gradle

dependencies {


implementation 'io.flutter:flutter_embedding_api:2.0.6'


// ... 其他依赖


}


4.2 使用FFI

在Flutter代码中,你可以使用`dart:ffi`包调用FFI库:

dart

import 'dart:ffi' as ffi;


import 'package:flutter/services.dart';

class FfiLibrary {


static final lib = ffi.DynamicLibrary.open('libnative');

static final getPlatformVersion = lib.lookupFunction<ffi.Pointer<ffi.Uint8> Function(), ffi.Pointer<ffi.Uint8> >('getPlatformVersion');


}

void main() {


runApp(MyApp());


}

class MyApp extends StatelessWidget {


@override


Widget build(BuildContext context) {


return MaterialApp(


home: Scaffold(


appBar: AppBar(


title: Text('Dart FFI Example'),


),


body: Center(


child: FutureBuilder<String>(


future: getPlatformVersion(),


builder: (context, snapshot) {


if (snapshot.connectionState == ConnectionState.waiting) {


return CircularProgressIndicator();


} else if (snapshot.hasError) {


return Text('Error: ${snapshot.error}');


} else {


return Text('Android ${snapshot.data}');


}


},


),


),


),


);


}


}


5. 总结

本文介绍了Flutter与Native代码交互的几种方法,包括平台通道、插件和Dart FFI。根据实际需求选择合适的方法,可以帮助你更好地实现Flutter应用的功能。