Flutter и нативное общение — плагин Flutter

внешний интерфейс Flutter

Эта статья в основном знакомит с принципом Flutter Plugin и процессом его разработки и выпуска.

предисловие

Преимущества Flutter в основном отражены в пользовательском интерфейсе — высокая производительность и стабильная производительность на разных платформах. Однако для реализации платформ (Android, IOS), таких как: получение питания, оценка использования WiFi, вызов WebView для загрузки веб-страниц и т. д., необходимо вызывать пакет API конкретной платформы. Плагин Flutter создан для вызова API платформы.

Упомянутая ниже «платформа» относится к обоим концам Android и IOS.

вводить

Flutter Plugin

Содержит собственные реализации для Android (код Java или Kotlin) или iOS (код Objective-C или Swift) черезPlatform ChannelsОбщайтесь со слоем FLutter (dart) и предоставляйте API.

Platform Channels

  • Позволяет обмениваться сообщениями между пользовательским интерфейсом Flutter и платформой.
  • Сообщения и ответы в каналах платформы доставляются асинхронно, чтобы пользовательский интерфейс оставался отзывчивым.
  • Приложение Flutter может иметь несколько каналов, используйтеnameкак отличие.
  • Канал платформы не线程安全, поэтому все взаимодействия между платформой и Flutter Engine должны осуществляться в主线程казнен в.
  • Кодек сообщений Flutter по умолчанию:StandardMessageCodec class, поддерживаемые типы данных платформы:

Создать плагин флаттера

Далее мы познакомимся с использованием Android Studio для создания плагина Flutter. Процесс использования Visual Studio Code для создания аналогичен, и вы можете сделать выводы из одного случая, поэтому я не буду здесь вдаваться в подробности.

Шаг 1: выберите создание проекта Flutter

Шаг 2. Выберите тип проекта Flutter в качестве плагина Flutter.

  • Приложение Flutter предназначено для создания чистого проекта проекта флаттера.
  • Плагин Flutter предназначен для создания проекта подключаемого модуля, который может предоставлять API платформы.
  • Пакет Flutter предназначен для создания чистого пакета компонентов Dart.
  • Модуль Flutter предназначен для создания модуля Flutter для внедрения в существующие нативные приложения.

Шаг 3: Заполните информацию о проекте, такую ​​как название проекта, и завершите создание плагина Flutter.

Структура каталогов после создания проекта выглядит следующим образом:

  • lib/flutter_plugin_eg.dart — это реализация dart API пакета плагинов.
  • android/src/main/ — это реализация пакета плагинов API Android.
  • ios/Classes/ — реализация пакета плагинов API IOS
  • пример — это чистый пример проекта флаттера, основанный на текущем плагине, который обычно используется для отображения вызовов API.

Примечание. Начиная с Flutter 1.9, новые проекты iOS по умолчанию используют Swift вместо Objective-C; новые проекты Android по умолчанию используют Kotlin вместо Java. Вы можете вернуться к предыдущей версии Objective-C или Java в любое время, если это необходимо.

Запустите пример проекта с помощью эмулятора Android.

Давайте сначала посмотрим на эффект выполнения примера проекта в эмуляторе Android:

Войдите в каталог примера проекта и запустите lib/main.dart.

После того, как приложение запустится на эмуляторе Android, вы увидите, что на экране появляется надпись «Работает на: Android 9».

Далее давайте посмотрим, как флаттер отображает системную версию текущей платформы через код.

Пример проекта example/lib/main.dart

Ключевой код:

...
import 'package:flutter_plugin_eg/flutter_plugin_eg.dart';
...
platformVersion = await FlutterPluginEg.platformVersion;
...
setState(() {
  _platformVersion = platformVersion;
});
...
body: Center(
  child: Text('Running on: $_platformVersion\n'),
)

lib/main.dart в примере проекта представляет реализацию dart API в плагине Flutter, который мы только что создали.flutter_plugin_eg.dart.

Затем вызовите его асинхронноflutter_plugin_eg.dartизFlutterPluginEg.platformVersionи присвоить возвращаемое значениеplatformVersion, с последующимsetStateметод положитьplatformVersionЗначение присваивается компоненту текущего состояния._platformVersion, запустить повторный рендеринг пользовательского интерфейса_platformVersionОтображается значение «Android 9».

Реализация dart API в плагине Flutter lib/flutter_plugin_eg.dart

Полный код:

import 'dart:async';

import 'package:flutter/services.dart';

class FlutterPluginEg {
  static const MethodChannel _channel =
      const MethodChannel('flutter_plugin_eg');

  static Future<String> get platformVersion async {
    final String version = await _channel.invokeMethod('getPlatformVersion');
    return version;
  }
}

  • service.dartПредоставьте API-интерфейсы, которые взаимодействуют с платформой, например:MethodChannelТип канала платформы
  • _channelявляется свойством класса FlutterPluginEg и представляет собой экземплярMethodChannel,nameдля "flutter_plugin_eg"
  • platformVersionявляется статическим классом FlutterPluginEg可计算属性, который асинхронно возвращает строку.
  • platformVersion, вызов_channelизinvokeMethodметод, входной параметр «getPlatformVersion» — это имя метода, согласованное с вызывающей платформой. тогда поставьinvokeMethodАсинхронный результат присваиваетсяString versionв видеplatformVersionВозвращаемое значение.

Реализация Android в плагине Flutter

android/src/main/kotlin/.../FlutterPluginEgPlugin.kt Полный код:

package com.yy.flutter_plugin_eg

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
import io.flutter.plugin.common.PluginRegistry.Registrar

class FlutterPluginEgPlugin: MethodCallHandler {
  companion object {
    @JvmStatic
    fun registerWith(registrar: Registrar) {
      val channel = MethodChannel(registrar.messenger(), "flutter_plugin_eg")
      channel.setMethodCallHandler(FlutterPluginEgPlugin())
    }
  }

  override fun onMethodCall(call: MethodCall, result: Result) {
    if (call.method == "getPlatformVersion") {
      result.success("Android ${android.os.Build.VERSION.RELEASE}")
    } else {
      result.notImplemented()
    }
  }
}

Еще раз: приложение Flutter может иметь несколькоchannel, и каждыйchannelможет иметь несколькоmethod, поэтому вам нужно сосредоточиться на том, как код платформы соединяется с именем канала и именем метода. Как видно из приведенного выше исходного кода .kt:

  • Зарегистрируйте имя канала соглашения MethodChannel «flutter_plugin_eg» и начните прослушивать сообщения канала.
companion object {
    @JvmStatic
    fun registerWith(registrar: Registrar) {
      val channel = MethodChannel(registrar.messenger(), "flutter_plugin_eg")
      channel.setMethodCallHandler(FlutterPluginEgPlugin())
    }
  }
  • Реализуйте метод onMethodCall, определите имя метода «getPlatformVersion» и вернитеAndroid ${android.os.Build.VERSION.RELEASE}
override fun onMethodCall(call: MethodCall, result: Result) {
    if (call.method == "getPlatformVersion") {
      result.success("Android ${android.os.Build.VERSION.RELEASE}")
    } else {
      result.notImplemented()
    }
  }

Когда имя канала и имя метода согласованы, плагин Flutter может легко вызвать реализацию платформы в dart и предоставить API для использования в проекте Flutter.

Реализация IOS в плагине Flutter

ios/Classes/SwiftFlutterPluginEgPlugin.swift

import Flutter
import UIKit

public class SwiftFlutterPluginEgPlugin: NSObject, FlutterPlugin {
  public static func register(with registrar: FlutterPluginRegistrar) {
    let channel = FlutterMethodChannel(name: "flutter_plugin_eg", binaryMessenger: registrar.messenger())
    let instance = SwiftFlutterPluginEgPlugin()
    registrar.addMethodCallDelegate(instance, channel: channel)
  }

  public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
    result("iOS " + UIDevice.current.systemVersion)
  }
}

Видно, что идеи реализации IOS и Android схожи: регистрируемся через "flutter_plugin_eg"FlutterMethodChannelи начать слушать.

Но я был удивлен, обнаружив, что код, сгенерированный swift по умолчанию в плагине Flutter, не имеет имени метода FlutterMethodCall, а имя метода «getPlatformVersion» можно получить из точки останова swift.

Эффект запуска на симуляторе IOS:

Выпуск плагина Flutter

После того, как колесо построено, его можно опубликовать вpub.dev, следующий контент - это просто движущиеся кирпичи.

Дополнительная документация

Добавьте в корневой каталог плагина Flutter

  • README.md: файл, представляющий пакет
  • CHANGELOG.md фиксирует изменения в каждой версии
  • Файл LICENSE, содержащий условия лицензии на программный пакет.
  • Пишите документацию по API

опубликовать пакет

После того, как вы внедрили пакет, вы можетеPubОпубликуйте его, чтобы другие разработчики могли легко его использовать.

Перед публикацией проверьте файлы pubspec.yaml, README.md и CHANGELOG.md, чтобы убедиться в целостности и правильности их содержимого.

Затем запустите команду пробного запуска, чтобы убедиться, что все готово:

flutter packages pub publish --dry-run

Наконец, запустите команду публикации:

flutter packages pub publish

Дополнительные сведения о публикации см.Pub publishing docs

считать

Чтобы разработать полнофункциональное приложение, в конечном счете, вам все равно нужно иметь возможность разрабатывать нативные платформы, точно так же, как Flutter Plugin необходимо разрабатывать нативные части платформы. Я считаю, что многие веб-интерфейсы для детской обуви также начали связываться с Flutter, но если у вас нет глубокого понимания нативной разработки, вы можете оставаться только на уровне пользовательского интерфейса.

автор

Doerme