Flutter MethodChannel 學習
好久沒寫東西,正好最近有時間又開始研究起來Flutter,不瞭解的童鞋可以去查查資料瞭解一下, 在我看來是目前我瞭解盜的最理想的跨平臺解決方案了。而跨平臺中一個比較重要的點就是與底層進行互動,本文就主要說一下在Flutter中是如何與Android進行通訊的(iOS應該同理)。不涉及到原始碼,只是簡單的使用和在使用過程中的一些想法。
建立初始的Demo
使用 flutter create methodchannellearn
建立一個 flutter
專案。
匯入 services
,async
包
import 'dart:async'; import 'package:flutter/services.dart';
首先先在main.dart
的 _MyHomePageState
中建立一個靜態成員變數methodChannel
static const MethodChannel methodChannel=const MethodChannel("flutter_method_channel");
然後修改原有的_incrementCounter()
方法,內部呼叫methodChannel.invokeMethod()
方法,呼叫Native端的方法。
void _incrementCounter() {
// setState(() {
// // This call to setState tells the Flutter framework that something has
// // changed in this State, which causes it to rerun the build method below
// // so that the display can reflect the updated values. If we changed
// // _counter without calling setState(), then the build method would not be
// // called again, and so nothing would appear to happen.
// _counter++;
// });
methodChannel.invokeMethod("_incrementCounter", _counter++);
}
複製程式碼
接下來就是在Android端新增響應的程式碼
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
new MethodChannel(getFlutterView(), "flutter_method_channel").setMethodCallHandler(
new MethodChannel.MethodCallHandler() {
@Override public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
if (methodCall.method.equals("_incrementCounter")) {
toast(methodCall.arguments);
}
}
});
}
複製程式碼
跑一下之後可以看到正常的toast彈出。
新增回撥
在onMethodCall
中我們可以看到還有另外的一個引數result
,可以使用它將資料傳遞迴Flutter中。
修改Android端程式碼
if (methodCall.method.equals("_incrementCounter")) {
if(methodCall.arguments instanceof Integer){
int count= (int) methodCall.arguments;
count++;
result.success(count);
}
}
複製程式碼
同時修改Flutter中的程式碼
Future<Null> _incrementCounter() async {
// setState(() {
// // This call to setState tells the Flutter framework that something has
// // changed in this State, which causes it to rerun the build method below
// // so that the display can reflect the updated values. If we changed
// // _counter without calling setState(), then the build method would not be
// // called again, and so nothing would appear to happen.
// _counter++;
// });
var result =
await methodChannel.invokeMethod("_incrementCounter", _counter);
setState(() {
_counter = result;
});
}
複製程式碼
執行一下,點選次數正常增加。
主動通知Flutter
有時候我們可能會需要主動的通知flutter ,而不是等待flutter呼叫,利用回撥傳遞資料,這是就需要一個新的Channel, EventChannel
同樣還是剛才的例子,這會先修改flutter
程式碼,使用EventChannel
static const EventChannel eventChannel =
const EventChannel("flutter_event_channel");
void _onData(event) {
setState(() {
_counter = event;
});
}
@override
void initState() {
// TODO: implement initState
super.initState();
eventChannel.receiveBroadcastStream().listen(_onData);
}
複製程式碼
然後修改Android的程式碼
new MethodChannel(getFlutterView(), "flutter_method_channel").setMethodCallHandler(
new MethodChannel.MethodCallHandler() {
@Override public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
if (methodCall.method.equals("_incrementCounter")) {
if (methodCall.arguments instanceof Integer) {
int count = (int) methodCall.arguments;
count++;
if (eventSink != null) {
eventSink.success(count);
}
}
}
}
});
new EventChannel(getFlutterView(), "flutter_event_channel").setStreamHandler(
new EventChannel.StreamHandler() {
@Override public void onListen(Object o, EventChannel.EventSink eventSink) {
MainActivity.this.eventSink = eventSink;
}
@Override public void onCancel(Object o) {
MainActivity.this.eventSink = null;
}
});
複製程式碼
同樣 執行,資料也能夠正常顯示
這裡EventChannel的使用場景應該會有好多,畢竟一個持久長時間的訊息通道在實際場景中會有很多應用。
專案的程式碼地址在這裡