先看一眼官方提供的demo:
Native端:
public class MainActivity extends FlutterActivity {
private String sharedText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
Intent intent = getIntent();
String action = intent.getAction();
String type = intent.getType();
if (Intent.ACTION_SEND.equals(action) && type != null) {
if ("text/plain".equals(type)) {
handleSendText(intent); // Handle text being sent
}
}
new MethodChannel(getFlutterView(), "app.channel.shared.data").setMethodCallHandler(
new MethodCallHandler() {
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
if (call.method.contentEquals("getSharedText")) {
result.success(sharedText);
sharedText = null;
}
}
});
}
void handleSendText(Intent intent) {
sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
}
}
flutter端:
void main() {
runApp(SampleApp());
}
class SampleApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Sample Shared App Handler',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: SampleAppPage(),
);
}
}
class SampleAppPage extends StatefulWidget {
SampleAppPage({Key key}) : super(key: key);
@override
_SampleAppPageState createState() => _SampleAppPageState();
}
class _SampleAppPageState extends State<SampleAppPage> {
static const platform = const MethodChannel('app.channel.shared.data');
String dataShared = "No data";
@override
void initState() {
super.initState();
getSharedText();
}
@override
Widget build(BuildContext context) {
return Scaffold(body: Center(child: Text(dataShared)));
}
getSharedText() async {
var sharedData = await platform.invokeMethod("getSharedText");
if (sharedData != null) {
setState(() {
dataShared = sharedData;
});
}
}
}
注意:app.channel.shared.data
两端保持一致。
一、 交互方式
* BasicMessageChannel:用于传递字符串和半结构化的信息,这个用的比较少
* MethodChannel:用于传递方法调用(method invocation)通常用来调用native中某个方法
* EventChannel: 用于数据流(event streams)的通信。有监听功能,比如电量变化之后直接推送数据给flutter端。
二、 channel通信的数据类型
在这里你不能传递一个bean文件过去。
三、使用方法
- 像MethodChannel可以直接看官方给的代码就好,其中Native中onMethodCall的Result对象是回调数据给flutter中使用的,有三个方法:
result.success(data); 成功的时候,返回数据调用
result.error() 失败的情况下,调用
result.notImplemented(); 这个是代表Native中的方法没有实现的话,可以告诉flutter方法没有实现
1.1 双向通讯
举个例子,我们想从Native端请求Flutter端的一个getFlutterName方法获取一个字符串。在Flutter端你需要给MethodChannel设置一个MethodCallHandler:
platform.setMethodCallHandler(platformCallHandler);
Future<dynamic> platformCallHandler(MethodCall call) async {
switch (call.method) {
case "getFlutterName":
return "Flutter name flutter";
break;
}
}
在Native端,只需要让对应的的channel调用invokeMethod就行了:
channel.invokeMethod("getFlutterName", null, new MethodChannel.Result() {
@Override
public void success(Object o) {
// 这里就会输出 "Flutter name flutter"
Log.i("debug", o.toString());
}
@Override
public void error(String s, String s1, Object o) {
}
@Override
public void notImplemented() {
}
});
- EventChannel的使用
官方给了一个获取电池电量的demo
Native端:
public class FlutterEventChannel implements EventChannel.StreamHandler {
private static final String TAG = "FlutterEventChannel";
private static final String EVENT_CHANNEL_NAME = "com.meetyou.flutter/event";
private FlutterEventChannel(FlutterView flutterView) {
EventChannel eventChannel = new EventChannel(flutterView, EVENT_CHANNEL_NAME);
eventChannel.setStreamHandler(this);
}
public static FlutterEventChannel create(FlutterView flutterView) {
return new FlutterEventChannel(flutterView);
}
private EventChannel.EventSink eventSink;
/**
* 暴露出去供界面传数据到Flutter
*/
public void sendEvent(Object data) {
if (eventSink != null) {
eventSink.success(data);
} else {
LogUtils.e(TAG, "===== FlutterEventChannel.eventSink 为空 需要检查一下 =====");
}
}
@Override
public void onListen(Object o, EventChannel.EventSink eventSink) {
this.eventSink = eventSink;
}
@Override
public void onCancel(Object o) {
eventSink = null;
}
}
后续数据传输
private BroadcastReceiver createChargingStateChangeReceiver(final EventSink events) {
return new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
if (status == BatteryManager.BATTERY_STATUS_UNKNOWN) {
events.error("UNAVAILABLE", "Charging status unavailable", null);
} else {
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
status == BatteryManager.BATTERY_STATUS_FULL;
// 把电池状态发给Flutter
events.success(isCharging ? "charging" : "discharging");
}
}
};
}
flutter端:
static const EventChannel eventChannel =
const EventChannel('com.meetyou.flutter/event');
@override
void initState() {
super.initState();
eventChannel.receiveBroadcastStream().listen(_onEvent, onError: _onError);
}
在收到event以后的处理是在_onEvent函数里:
void _onEvent(Object event) {
setState(() {
_chargingStatus =
"Battery status: ${event == 'charging' ? '' : 'dis'}charging.";
});
}
void _onError(Object error) {
setState(() {
_chargingStatus = 'Battery status: unknown.';
});
}
从Native端传过来的"charging"/"discharging"字符串直接就是入参event.
有关可以参考的文章还有:
Flutter 实例 - 从本地到Flutter通信 - Event Channels
flutter通讯
深入理解Flutter Platform Channel