Flutter from entry to abandonment
background
From setup to project development, Flutter has been in the pit for almost a week. I have to say, from an Android native developer’s perspective, Flutter is relatively friendly compared to other cross-platform solutions in terms of performance, UI rendering and learning costs. It maintains several sets of UI logic internally, skia engine rendering, But understand that Flutter is always a cross-platform UI solution and ultimately generates.apk(Android)/.ipa(ios) packages based on the platform. Therefore, when it comes to some system platform interfaces or data, For example, the system electricity needs to be handled by the Native layer, and then the data is returned to the flutter layer for display. Therefore, it is inevitable that there will be communication problems between the flutter and the native layer. Then, how does the flutter achieve this? Platform Channels
Platform Channels
The diagram above from the Website of Flutter shows the architecture of Platform Channels. Don’t you say that Flutter and Native communicate through Platform Channels? How come the schema connects them with a MethodChannel? Actually, MethodChannel is a type of Platform Channels, and as the name implies, MethodChannel should be used much like a method call. So there are other channels? Yes, there are EventChannel, BasicMessageChannel, etc. If you need to send data from Native to Flutter, EventChannel is recommended. The Flutter framework also uses these channels to communicate with Native
Example 1: Flutter calls Android logcat
Although Flutter itself provides two log output methods: print() and debugprint(), it is not very comfortable for Android developers. Information is redundant in the console bar and cannot be filtered, etc. So you can call android native Logcat through Channels
The Flutter end
import 'package:flutter/services.dart';
class LogUtils {
static const perform = const MethodChannel("android_log");
static void v(String tag, String message) {
perform.invokeMethod('logV', {'tag': tag, 'msg': message});
}
static void d(String tag, String message) {
perform.invokeMethod('logD', {'tag': tag, 'msg': message});
}
static void i(String tag, String message) {
perform.invokeMethod('logI', {'tag': tag, 'msg': message});
}
static void w(String tag, String message) {
perform.invokeMethod('logW', {'tag': tag, 'msg': message});
}
static void e(String tag, String message) {
perform.invokeMethod('logE', {'tag': tag, 'msg': message}); }}Copy the code
As you can see, the code is simple: initialize a MethodChannel object and then call the invokeMethod method, passing in the parameters
The android end
public class MainActivity extends FlutterActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
new MethodChannel(getFlutterView(),CHANNEL).setMethodCallHandler(new MethodChannel.MethodCallHandler() {
@Override
public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
String tag = methodCall.argument("tag");
String msg = methodCall.argument("msg");
switch (methodCall.method) {
case "logV":
Log.v(tag,msg);
break;
case "logD":
Log.d(tag,msg);
break;
case "logI":
Log.i(tag,msg);
break;
case "logW":
Log.w(tag,msg);
break;
case "logE":
Log.e(tag,msg);
break;
default:
Log.d(tag,msg);
break; }}}); }Copy the code
MethodCallHandler (); method (); arguments (); log ();
Example 2: Android pushes messages to Flutter
Because most of the current flutter and native development, many flutter needs to actively push messages to the native layer. The native layer can create an EventChannel to monitor the status of flutter and then reply the message OBJ through the EventSink object
The android end
new EventChannel(getFlutterView(), "com.flutter/notify").setStreamHandler(
new EventChannel.StreamHandler() {
private TokenReceiver tokenReceiver;
@Override
public void onListen(Object args, final EventChannel.EventSink events) {
Log.e("tag"."adding listener");
events.success("data callback");
}
@Override
public void onCancel(Object args) {
Log.e("tag"."cancelling listener"); }});Copy the code
flutter
static const EventChannel eventChannel = EventChannel('com.flutter/notify');
@override
void initState() {
// TODO: implement initState
super.initState();
// Initialize the listener
eventChannel.receiveBroadcastStream().listen(_onDataBack, onError: _onError);
}
void _onError(Object error){
}
void _onDataBack(String callback) {
print(callback)
}
Copy the code
Create an EventChannel with the same Channel name and listen for the data to do the corresponding logic