(本文只列出與Android Native的交互,iOS使用相同的Api,處理方式類似)。主要就是 MethodChannel的使用,因爲native端和flutter端都有 methodChannel的setMethodCallHandler(),和invokeMethod()方法,所以兩端都可以使用methodChannel進行通信。
Dart調用Native源碼:
//Dart端源碼
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
...
class _MyHomePageState extends State<MyHomePage> {
static const platform = const MethodChannel('samples.flutter.dev/battery');
// Get battery level.
}
// Get battery level.
String _batteryLevel = 'Unknown battery level.';
Future<void> _getBatteryLevel() async {
String batteryLevel;
try {
final int result = await platform.invokeMethod('getBatteryLevel');
batteryLevel = 'Battery level at $result % .';
} on PlatformException catch (e) {
batteryLevel = "Failed to get battery level: '${e.message}'.";
}
setState(() {
_batteryLevel = batteryLevel;
});
}
//Native端,Android Java.(Kotlin類似)。交互代碼運行在mainThread主線程。
import io.flutter.app.FlutterActivity;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "samples.flutter.dev/battery";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
new MethodCallHandler() {
@Override
public void onMethodCall(MethodCall call, Result result) {
// Note: this method is invoked on the main thread.
if (call.method.equals("getBatteryLevel")) {
int batteryLevel = getBatteryLevel();
if (batteryLevel != -1) {
result.success(batteryLevel);
} else {
result.error("UNAVAILABLE", "Battery level not available.", null);
}
} else {
result.notImplemented();
}
}
});
}
}
Native發送給flutter數據:(同樣使用methodChannel機制)
//native 端。這裏是Kotlin,Java類似。
const val CONNECTION_CHANNEL = "com.demo.flutter.connection"
val methodChannel = MethodChannel(flutterView, CONNECTION_CHANNEL)
methodChannel.setMethodCallHandler { methodCall, result ->
when (methodCall.method) {
"activityFinish" -> {
goBack() //關閉當前頁面
result.success(null) //標識調用成功
}
"showToastMessage" -> showShortToast(methodCall.argument<String>("message"))
}
}
//使用註冊的方法channel調用dart端方法名稱,並傳遞參數。
Handler().postDelayed({
methodChannel.invokeMethod("aaa", "c")
}, 5000);
//dart端
static const _platform = const MethodChannel("com.whitehorse.flutter.connection");
_AboutPageState() {
_platform.setMethodCallHandler((handler) {
switch (handler.method) {
case "aaa":
_platform.invokeMethod("showToastMessage", {"message": "您調用了dart裏的方法"});
break;
}
});
}
void _goBack() {
// _platform.invokeMethod("activityFinish");
}
另一種方式,實現native flutter通信:
基於 EventChannel,使用事件流 event stream 驅動,更適合長久耗時的方法調用。
//Native端,android.
public class MainActivity extends FlutterActivity {
public static final String STREAM = "com.yourcompany.eventchannelsample/stream";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new EventChannel(getFlutterView(), STREAM).setStreamHandler(
new EventChannel.StreamHandler() {
@Override
public void onListen(Object args, final EventChannel.EventSink events) {
Log.w(TAG, "adding listener");
}
@Override
public void onCancel(Object args) {
Log.w(TAG, "cancelling listener");
}
}
);
}
}
//flutter,dart端
static const stream =
const EventChannel('com.yourcompany.eventchannelsample/stream');
StreamSubscription _timerSubscription = null;
void _enableTimer() {
if (_timerSubscription == null) {
_timerSubscription = stream.receiveBroadcastStream().listen(_updateTimer); // 添加監聽
}
}
void _disableTimer() {
if (_timerSubscription != null) {
_timerSubscription.cancel();
_timerSubscription = null;
}
}
* flutter receiveBroadcastStream([arguments]) 返回一個 broadcast stream對象。使用API進行操作。
https://api.flutter.dev/flutter/dart-async/Stream-class.html。
常用的爲 listener。