目前Flutter社区正处在一个蓬勃发展的阶段,pub.dev上也提供了数不清的插件供大家使用。但是很多时候由于各种原因别人的插件可能会没有我们想要的功能,更严重的有的还会出现一些致命性Bug。
这个时候就需要我们自己动手添加自己想要的功能或来修复别人的Bug,随之而来的就是如何调试插件。
关于插件的开发网上已经有很多不错的教程。不管是集成到自己项目还是打包发布到Pub上都有很详细的介绍。
这些教程都从原理和实现等方方面面介绍了如何开发插件。
总结下来开发插件无外乎实现两种功能:
一是方法调用的数据传递。大多数插件都是这种类型的,用来完成手机硬件控制或原生方法回调。
-
在Flutter端:
-
在方法调用用常用
MethodChannel使用同一个名称和IOS/Android端建立通道连接,然后调用invokeMethod方法调用其他平台方法。 -
监听回调可以使用
setMethodCallHandler实现回调逻辑,也可以使用EventChannel来实现;
-
-
在其他端:
-
使用注册插件时传递的
Message对象和相同的名称生成MethodChannel通道。 -
实现
setMethodCallHandler回调方法就可以接受Flutter传递过来的数据。
-
二是视图调用的数据传递。 使用原生视图相对于方法调用复杂一点,但也是建立相同名称的MethodChannel来实现数据交互。
-
在Flutter端:
-
创建
Widget,在Build中根据平台返回不同的系统Widget,Android端返回AndroidView,IOS端返回UiKitView,并在viewType参数中给该Widget赋上必须的唯一标识符,并保证在两段注册视图时一致。 -
如果需要调用改视图原生方法则最好创建
Controller类来管理视图方法,通过onPlatformViewCreated方法中传递的ID参数来生成该视图控制器的数据传输通道。
-
///NativeView
@override
Widget build(BuildContext context) {
if (Platform.isAndroid) {
return AndroidView(
viewType: 'native_view_type',
onPlatformViewCreated: (id) => NativeViewController(id),
);
} else if (Platform.isIOS) {
return UiKitView(
viewType: 'native_view_type',
onPlatformViewCreated: (id) => NativeViewController(id),
);
} else {
return Text("不支持的平台");
}
}
///NativeViewController
class NativeViewController {
final MethodChannel _channel;
NativeViewController(int id)
: _channel = MethodChannel('native_view_type_$id');
}
-
在其他端:
-
创建视图工厂类来生成视图。通过实现
FlutterPlatformViewFactory协议中方法,返回自定义的原生视图。并使用注册时的Message对象和相同的名称native_view_type_$id给改视图创建MethodChannel。 -
调用
registerViewFactory方法来注册该视图工厂并保证与viewType相同的名称。 -
实现自定义原生视图,并实现
FlutterPlatformView协议。如果该视图为View的子类那么直接返回自身就可以了。 -
原生视图实现通道的
setMethodCallHandler方法来实现方法调用。
-
///生成并注册视图工厂类
NativeViewFactory *nativeViewFactory = [[NativeViewFactory alloc]initWithMessage:[registrar messenger]];
[registrar registerViewFactory:nativeViewFactory withId:@"native_view_type"];
///工厂类实现该协议
- (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id _Nullable)args {
NativeView *nativeView = [[NativeView alloc]initWithFrame:frame];
nativeView.channel = [FlutterMethodChannel methodChannelWithName:[NSString stringWithFormat:@"%@_%lld",@"native_view_type",viewId] binaryMessenger:self.message];
return nativeView;
}
///原生视图实现该协议
- (UIView *)view {
return self;
}
调试插件Debug
当我们使用编译器运行起程序时,可以使用Attach连接正在运行程序的设备就可以实现不同编译器同时打断点调试。
例如:
在Xcode上运行ios模块,在Android Studio中点击attach图标。
也可以参考在混合应用模式下进行调试。