Flutter 原生外掛開發流程

ldx發表於2019-11-04

一、Package型別

1、純Dart庫

用Dart編寫的傳統package,依賴於Flutter框架,使用返回僅限於Flutter;

2、原生外掛

使用Dart編寫,按需使用Java(kotlin)或Objc(Swift),分別在Android 和 iOS平臺實現的package。

二、原生外掛型別的Package的開發

1、建立Package

flutter create --org com.example --template=plugin pluginName
複製程式碼

預設情況下,iOS程式碼使用swift語言編寫,Android程式碼使用Kotlin語言編寫。但是你可以通過 -i 指定iOS的語言;-a指定Android的開發語言。

flutter create --template=plugin -i objc -a java pluginName
複製程式碼

pluginName目錄下會建立一個外掛工程:

  • lib/pluginName.dart:
    • Dart 外掛 API 實現。
  • android/src/main/java/com/example/​hello/PluginNamePlugin.kt:
    • Android 平臺原生外掛 API 實現。
  • ios/Classes/PluginNamePlugin.m:
    • iOS 平臺原生外掛 API 實現。
  • example/:
    • 一個依賴於該外掛並說明了如何使用它的 Flutter 應用。

2、實現Package

2.1、定義PackageApi(.dart部分)

原生外掛型別 package 的 API 在 Dart 程式碼中要首先定義好,使用 Flutter 編輯器,開啟 pluginName/ 主目錄,並找到 lib/pluginName.dart 檔案。

這一步定義了與原生互動的欄位等資訊。

2.2、Android平臺

  • 編譯apk
    • 進入pluginName/example目錄下;
    • 執行 flutter build apk
  • 進入工程pluginName/example/Android
    • PluginNamePlugin.kt下新增Android程式碼;
  • Project Structure目錄下
    • Modules中,pluginName_androidpluginName_example_android下的sources可以去掉
  • 執行即可檢視結果。
  • 示例程式碼
class FlutterCryptoPlugin: MethodCallHandler {
  @JvmField val CHARSET = Charsets.UTF_8

  companion object {
    @JvmStatic
    fun registerWith(registrar: Registrar) {
      val channel = MethodChannel(registrar.messenger(), "flutter_crypto_plugin")
      channel.setMethodCallHandler(FlutterCryptoPlugin())
    }
  }

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

2.3、iOS平臺

  • 編譯
    • 進入pluginName/example目錄;
    • 執行flutter build ios --no-codesign
  • 如果需要第三方
    • 進入檔案pluginName.podspec檔案;
    • 新增需要的第三方,示例:s.dependency 'CryptoSwift', '~> 0.13.1'
  • 用xcode開啟pluginName/example/ios/Runner.xcworkspace
    • 外掛程式碼位於Pods/DevelopmentPods/hello/Classes/
  • 示例程式碼
public class SwiftFlutterCryptoPlugin: NSObject, FlutterPlugin {
      
    public static func register(with registrar: FlutterPluginRegistrar) {
        let channel = FlutterMethodChannel(name: "flutter_crypto_plugin", binaryMessenger: registrar.messenger())
        let instance = SwiftFlutterCryptoPlugin()
        registrar.addMethodCallDelegate(instance, channel: channel)
    }
    
    public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
        if call.method == "getPlatformVersion" {
            result("iOS " + UIDevice.current.systemVersion)
        } else if call.method == "..." {
        // todo 
        } else {
        	result(FlutterMethodNotImplemented)
        }
   }
}
複製程式碼

3、新增文件

  • README.md:介紹包的檔案
  • CHANGELOG.md 記錄每個版本中的更改
  • LICENSE 包含軟體包許可條款的檔案
  • 所有公共API的API文件 (詳情見下文)

4、釋出Package

4.1、執行 dry-run 命令以檢視是否都準備OK

flutter packages pub publish --dry-run
複製程式碼

4.2、執行釋出

flutter packages pub publish
複製程式碼

5、本地新增開發的Package

5.1、上傳到了pub

dependencies:
  flutter:
    sdk: flutter
  // 三方包
  pluginName: ^0.0.1
複製程式碼

5.2、本地新增

dependencies:
    // 包名
    pluginName:
        // 本地包路徑:可以是相對路徑,也可以是絕對路徑
        path: ../../code/pkg1

複製程式碼

5.3、git遠端倉庫

dependencies:
  // 包名
  pluginName:
    git:
      // 遠端倉庫 url
      url: .....
      // 遠端倉庫中的包的相對路徑
      path: packages/package1
複製程式碼

相關文章