Flutter插件
簡介
Flutter 的庫是以 package 的方式來管理恒削。Package 分為兩種卿捎,Dart package(也叫 library package) 和 plugin package巩割。日常使用的 import 'package:flutter/material.dart';
就是 Dart 包,它只能使用 Dart 和 Flutter 提供的 API, 決定了它只能用在 Flutter 上油坝;今天文章內容主要講解 Flutter 插件開發(fā)指的是后者,即 plugin package棒呛。Flutter 插件既包含了dart代碼編寫的api,又包含了平臺( Android/iOS )特定實現的package域携,可以被 Android 和 iOS 調用簇秒。
使用
可以在 pub.dev 網站查找你所需要的包。
我們以 shared_preferences 這個庫為例秀鞭,在項目中的 pubspec.yaml
聲明一個依賴:
dependencies:
shared_preferences: ^0.5.2
^0.5.2
與 0.5.2 兼容的版本版本號趋观,同時你也可以使用如下格式:
- any:任意版本
- 1.2.3:特定的版本
- <1.2.3:小于 1.2.3 的版本,此外還有 <=锋边、>皱坛、>= 可以使用
=1.2.3 <2.0.0’:指定一個范圍
更加詳細的配置可以參考 versioning
保存后 Android Studio
會自動去下載此包,或者通過命令豆巨,在項目的根目錄執(zhí)行 flutter packages get
使用就相對簡單了剩辟,如下:
import 'package:shared_preferences/shared_preferences.dart';
開發(fā)
插件通信機制
如上圖所示,Flutter 跟平臺相關代碼可以通過 MethodChannel
進行通信往扔》妨裕客戶端通過 MethodChannel
將方法調用和參數發(fā)生給 Flutter
,Flutter
也通過 MethodChannel
接收相關的數據萍膛。
消息和響應是異步傳遞的吭服,以確保用戶界面保持響應(不會掛起)
創(chuàng)建插件項目
接下來利用 Android Studio
來進行插件開發(fā), 創(chuàng)建成功后,目錄結構如下:
- android:插件本地代碼的 Android 端實現
- ios:iOS 端的實現
- lib:Dart 代碼卦羡。插件的客戶將會使用這里實現的接口
- example:插件的使用示例
- test: 測試
其中噪馏,一個最package最少包含了兩部分: * 一個pubspec.yaml文件:元數據文件,聲明了package的名稱绿饵、版本欠肾、作者等信息。
一個lib文件夾:包含里package的公開代碼拟赊,文件夾至少需要存在<pakcage-name>.dart這個文件刺桃。
也可以利用 Flutter
命令來生成
flutter create --org com.kinsomy --template=plugin -i swift -a kotlin hello
默認情況下,創(chuàng)建的plugin項目是使用 objective-c(iOS)和 java(Android)編寫吸祟,如果需要增加對swift和kotlin的支持瑟慈,可以在命令中添加 -i 和 -a。
注意點:插件命名符合 lowercase_with_underscores
編寫 iOS 插件
Flutter 與 iOS 通信
!
Dart 代碼
import 'dart:async';
import 'package:flutter/services.dart';
class FlutterPluginTest {
static const MethodChannel _channel =
const MethodChannel('flutter_plugin_test');
static Future<String> get platformVersion async {
final String version = await _channel.invokeMethod('getPlatformVersion');
return version;
}
}
iOS 代碼
@implementation FlutterPluginTestPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
FlutterMethodChannel* channel = [FlutterMethodChannel
methodChannelWithName:@"flutter_plugin_test"
binaryMessenger:[registrar messenger]];
//兩種回調方式:
//1.代理本質:內部調用channel 的Block執(zhí)行代理函數
FlutterPluginTestPlugin* instance = [[FlutterPluginTestPlugin alloc] init];
[registrar addMethodCallDelegate:instance channel:channel];
// //2.
// channel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
//
// }
}
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
if ([@"getPlatformVersion" isEqualToString:call.method]) {
result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
} else {
result(FlutterMethodNotImplemented);
}
}
@end
其中屋匕,在 dart 端傳入參數被解析為Map ,到了 oc 中會變成 NSDictionary
,然后通過 key 獲取到對應的值
如下為:類型對應表
iOS 與 Flutter 通信
Dart端
Channel.setMethodCallHandler((MethodCall call) async {
assert(call.method == 'launch');
handler(call.arguments);
});
iOS端
[self.channel invokeMethod:@"FunctionName" arguments:參數];
補充
在 通信機制中葛碧,還有兩類 FlutterEventChannel,FlutterBasicMessageChannel过吻,同時在Dart端使用同類型的Channel