Wenn wir mit einem plattformübergreifenden Framework arbeiten, ist es nicht möglich, zu garantieren, dass wir nur mit diesem Framework arbeiten werden, ohne dass der native Code bearbeitet wird. Entwickler werden höchstwahrscheinlich auf nativen Code zurückgreifen, entweder wegen Funktionen, die das Framework noch nicht bietet, oder wegen Leistungsproblemen, die nur in nativem Code gelöst werden können. Plattformkanäle sind die Methode, mit der Sie plattformspezifischen nativen Code schreiben können, der in Ihren Flutter-Anwendungen verwendet wird.

Die Standard-Plattformkanäle verwenden einen Standard-Nachrichtencodec, der eine effiziente binäre Serialisierung von einfachen JSON-ähnlichen Werten unterstützt, wie z. B. Booleans, Zahlen, Strings, Bytepuffer sowie Listen und Maps aus diesen. Die Serialisierung und Deserialisierung dieser Werte in und aus Nachrichten erfolgt automatisch, wenn Sie Werte senden und empfangen.

Platform Channel besteht aus drei Teilen: MethodChannel-Klasse auf Flutter, MethodChannel-Klasse auf Android und FlutterMethodChannel-Klasse auf iOS.

Der Vorteil von Flutter ist, dass es ein flexibles System verwendet, das es erlaubt, plattformspezifische APIs aufzurufen, egal ob sie in Kotlin oder Java-Code auf Android oder in Swift oder Objective-C-Code auf iOS verfügbar sind.

Dieses Tutorial zeigt, wie man eine Flutter-Funktion erstellt, die nativen Code für Android und iOS aufruft.

 

Aufruf von nativen Funktionen aus Flutter

Die Anwendung wird eine Funktion entsprechend ihrem Namen aufrufen und das Programm wird nach ihrer Implementierung im Android- oder iOS-Code suchen.

Erstellen Sie zunächst einen MethodChannel.

Die Client- und die Host-Seite des Kanals werden über den im Kanalkonstruktor übergebenen Kanalnamen verbunden. Alle Kanalnamen, die in einer einzigen App verwendet werden, müssen eindeutig sein.

 

static final channelName = 'example.channel/native';
const methodChannel = MethodChannel(channelName);

Erstellen Sie dann eine Methode, die die angegebene Methode auf dem Plattformkanal aufruft.

Future<void> _getBatteryLevel() async {
    String batteryLevel;
    try {
        batteryLevel = await platform.invokeMethod('getBatteryLevel');
    } on PlatformException catch (e) {
        batteryLevel = e.message;
    }
}

Android

Navigieren Sie zum Verzeichnis mit der Flutter-App und öffnen Sie den Ordner android in Android Studio.

Öffnen Sie die Datei MainActivity.kt. Erstellen Sie denselben Kanal, den Sie in Ihrem Flutter-Teil deklariert haben.

 

private val channelName ='example.channel/native'

Then inside configureFlutterEngine() add method call handler.

MethodChannel(flutterEngine.dartExecutor.binaryMessage, channelName)
    .setMethodCallHandler { call, result ->
        if (call.method == "getBatteryLevel") {
            val batteryLevel = getBatteryLevel()
            result.success(batteryLevel)
        } else {
            result.notImplemented()
        }
    }

Als Nächstes fügen Sie die Implementierung der Methode hinzu, die Sie aufrufen möchten (im Beispiel die Funktion getBatteryLevel() ).

iOS

Öffnen Sie den Ordner ios in XCode. Gehen Sie zur Datei AppDelegate.swift und erstellen Sie innerhalb der Funktion application:didFinishLaunchingWithOptions einen Kanal.

  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    
    let channelName = "example.channel/native"
    let rootViewController : FlutterViewController = window?.rootViewController as! FlutterViewController
    let methodChannel = FlutterMethodChannel(name: channelName, binaryMessage: rootViewController)

    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)

  }

Als nächstes fügen Sie einen Methodenaufruf-Handler hinzu.

methodChannel.setMethodCallHandler( {(call: FlutterMethodCall, result: FlutterResult) -> Void in
    guard call.method == "getBatteryLevel" else {
        result(FlutterMethodNotImplemented)
        return
    }
    self?.getBatteryLevel(result: result)
})

Methodenimplementierung erstellen (im Beispiel getBatteryLevel).

Umgekehrtes Beispiel

Wenn Sie eine Flutter-Methode von nativem Code aus aufrufen müssen, rufen Sie die gleichen Methoden von früher auf, aber umgekehrt.

Flutter code

static final channelName = 'example.channel/native'; 
const methodChannel = MethodChannel(channelName);
methodChannel.setMethodCallHandler(_nativeMethodCallHandler);

Future<dynamic> _nativeMethodCallHandler(MethodCall call) async {
    switch(call.method) {
        case "exampleMethod":
            //function call
    }
}

Android code

val channelName = 'example.channel/native'
val methodChannel = MethodChannel(flutterView, channelName)

methodChannel.invokeMethod("exampleMethod")

iOS code

let rootViewController : FlutterViewController = window?.rootViewController as! FlutterViewController
let channelName ="example.channel/native"
let methodChannel = FlutterEventChannel(name: channelName, binaryMessenger: rootViewController)

methodChannel.invokeMethod("exampleMethod")