Flutter 與 Android 的互通主要通過以下幾種方式實現,每種方式適用于不同的場景:
1. 平臺通道(Platform Channels)
Flutter 與原生 Android 代碼通信的核心方式,支持雙向調用。
類型:
- MethodChannel:雙向方法調用(最常用)
- EventChannel:用于原生向 Flutter 發送事件流(如傳感器數據)
- BasicMessageChannel:簡單的消息傳遞(較少使用)
示例(MethodChannel):
// Flutter 側(Dart)
const channel = MethodChannel('com.example/app');
Future<void> getNativeData() async {try {final String result = await channel.invokeMethod('getData');print('原生返回: $result');} on PlatformException catch (e) {print('調用失敗: ${e.message}');}
}
// Android 側(Kotlin)
class MainActivity : FlutterActivity() {override fun configureFlutterEngine(flutterEngine: FlutterEngine) {super.configureFlutterEngine(flutterEngine)MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "com.example/app").setMethodCallHandler { call, result ->if (call.method == "getData") {result.success("Hello from Android!")} else {result.notImplemented()}}}
}
2. 插件(Plugins)
封裝原生功能的可復用模塊,社區或官方提供(如相機、定位等)。
使用步驟:
- 添加依賴(
pubspec.yaml
):dependencies:url_launcher: ^6.0.0
- 調用插件:
import 'package:url_launcher/url_launcher.dart'; Future<void> launchURL() async {if (await canLaunch('https://flutter.dev')) {await launch('https://flutter.dev');} }
自定義插件:
通過 flutter create --template=plugin
生成插件模板,自動生成平臺通道代碼。
3. 平臺視圖(Platform Views)
在 Flutter 中嵌入原生 Android 控件(如 WebView、地圖)。
示例(嵌入 Android View):
// Flutter 側
Widget build(BuildContext context) {return AndroidView(viewType: 'native_view',creationParams: {'text': 'Flutter傳遞的參數'},creationParamsCodec: StandardMessageCodec(),);
}
// Android 側注冊視圖
class NativeViewFactory : PlatformViewFactory(StandardMessageCodec.INSTANCE) {override fun create(context: Context, id: Int, args: Any?): PlatformView {val params = args as Map<String, Any>return NativeView(context, params["text"] as String)}
}// 在 FlutterActivity 中注冊
flutterEngine.platformViewsController.registry.registerViewFactory("native_view", NativeViewFactory()
)
4. 直接調用原生 Activity/Service
從 Flutter 啟動 Android 原生頁面或服務。
示例:
// Flutter 側
const channel = MethodChannel('com.example/activity');
Future<void> startNativeActivity() async {await channel.invokeMethod('startVideoPlayer', {'url': 'video.mp4'});
}
// Android 側
MethodChannel(flutterEngine.dartExecutor, "com.example/activity").setMethodCallHandler { call, result ->if (call.method == "startVideoPlayer") {val url = call.argument<String>("url")val intent = Intent(this, VideoPlayerActivity::class.java).apply {putExtra("videoUrl", url)}startActivity(intent)result.success(null)}
}
5. 數據共享
通過共享存儲(如 SharedPreferences、數據庫)傳遞數據。
示例(SharedPreferences):
// Flutter 側
final prefs = await SharedPreferences.getInstance();
await prefs.setString('token', 'abc123');
// Android 側讀取(同一文件)
val prefs = getSharedPreferences("FlutterSharedPreferences", MODE_PRIVATE)
val token = prefs.getString("flutter.token", "") // 注意鍵名前綴 `flutter.`
6. FFI(Foreign Function Interface)
直接調用 C/C++ 代碼(通過 dart:ffi
),適用于高性能計算或底層操作。
適用場景:
- 調用現有的 C/C++ 庫。
- 需要極致性能的模塊(如圖像處理)。
如何選擇?
場景 | 推薦方式 |
---|---|
簡單方法調用 | MethodChannel |
持續事件監聽(如傳感器) | EventChannel |
復用社區功能(如相機) | Plugins |
嵌入復雜原生控件 | Platform Views |
啟動原生頁面 | 調用 Activity/Service |
共享簡單數據 | SharedPreferences |
高性能原生代碼交互 | FFI |
注意事項
- 線程問題:原生代碼默認在 UI 線程執行,耗時操作需切換到子線程。
- 異步處理:Flutter 側使用
Future
,原生側需調用result.success()
或result.error()
。 - 性能:頻繁跨平臺通信可能影響性能,盡量批量傳遞數據。
通過合理選擇這些方式,可以無縫結合 Flutter 的跨平臺優勢與 Android 的原生能力。