使用过Flutter开发的攻城狮都知道,Flutter现有的插件虽然已很丰富,但是某些场景依然无法实现,比如我们自身应用的加解密,特定业务场景的处理,此时需要插件来支撑,攻城狮们可以直接在flutter工程的android工程/ios工程目录下直接新增相应的逻辑,并通过MethodChannel 和 EventChannel来进行交互

复杂的场景,比如这块插件内容不止于本项目工程使用,另外工程也会使用,这个时候我们可以抽离出来,单独写这样的插件,然后供项目去使用,就不需要来回的copy代码了

接下来我会把自己创建插件的步骤罗列出来,以及MethodChannel和EventChannel在插件中的使用分发,大家有任何问题可以评论,一起学习成长,由于本博主是Android攻城狮,所以我主要讲解Android端

进入正题:

1、首先我们要New 一个 Flutter Plugin插件工程

Flutter android studio 扩张插件 flutter开发插件_flutter


2、该工程默认生成了一个dart入口程序,android工程下已有一个Plugin

3、此时打开该插件的Android工程,会发现找不到io.flutter.plugin.*,也即找不到flutter.jar包,此时需要针对该问题做以下检查以及配置

1)

Flutter android studio 扩张插件 flutter开发插件_flutter_02


2)

Flutter android studio 扩张插件 flutter开发插件_android_03


def localProperties = new Properties()
 def localPropertiesFile = rootProject.file(‘local.properties’)
 if (localPropertiesFile.exists()) {
 localPropertiesFile.withReader(‘UTF-8’) {
 reader -> localProperties.load(reader)
 }
 }
 //获取flutter的sdk路径
 def flutterRoot = localProperties.getProperty(‘flutter.sdk’)
 if (flutterRoot == null) {
 throw new GradleException(“Flutter SDK not found. Define location with flutter.sdk in the local.properties file.”)
 }
 dependencies {
 implementation “org.jetbrains.kotlin:kotlin-stdlib-jdk7:flutterRoot/bin/cache/artifacts/engine/android-arm/flutter.jar”) compileOnly ‘androidx.annotation:annotation:1.1.0’
 }

3)此时在同步项目,如果项目可以跑起来,则可以进行接下来的操作

4、此时我们看Android工程下的plugin文件,可以看到只是实现了MethodChannel,如果我们也需要EventChannel这种操作后的通知行为时,我们需要实现EventChannel.StreamHandler,然后进行EventChannel的初始化,这里注意一下,EventChannel的name不要和MethodChannel的名字一样

5、参照我的例子如下

Flutter android studio 扩张插件 flutter开发插件_Android_04


大家注意到以上图片我同样实现了 ActivityResultListener, ActivityAware

ActivityResultListener 监听startActivityForResult返回的结果,如果我们有这种场景,记得实现

ActivityAware 获取当前上下文Activity对象,以方便用到Activity上下文时的操作,这两个用法不多说,大家有要了解的可以私下去看下,相对比较简单

至此,android层的例子结束,大家可以看到我定义了两个方法

getPlatformVersion 和 getString,getString方法,同时用eventSink回调给了flutter层一个通知内容

6、flutter层的实现

class ZhwLoginPlugin{
 final MethodChannel _channel ;
 final EventChannel _eventChannel ;
 static ZhwLogin _instance;
//如果有多个分发结果需要处理,可以定义多个StreamController,然后在客户端进行监听
 //StreamController的类型 T 可以是任何类型,对象,map等都可以,接收的时候亦如此接收即可
 StreamController _getStringStreamController = StreamController.broadcast();
//客户端监听 initState()方法中 ZhwLogin().getStringResp.listener((event) {})
 Stream get getStringResp => _getStringStreamController.stream;//factory Flutter单例模式,在这里面进行初始化操作
 factory ZhwLogin(){
 if (_instance == null) {
 final MethodChannel methodChannel = const MethodChannel(“zhw_login”);
 final EventChannel eventChannel = const EventChannel(‘zhw_login_event’);
 //初始化操作
 _instance = ZhwLogin._private(methodChannel, eventChannel);
 }
 return _instance;
 }
 ZhwLogin._private(this._channel,this._eventChannel){
 //初始化监听
 _eventChannel.receiveBroadcastStream().listen(_onEvent, onError: _onError);
 }Future get platformVersion async {
 final String version = await _channel.invokeMethod(‘getPlatformVersion’);
 return version;
 }void getString(){
 _channel.invokeMethod(“getString”);
 }void parseGetStringNotification(String eventString){
 _getStringStreamController.add(eventString);
 }void _onEvent(Object event) {
 print(“监听到Android端EventChannel返回==$event”);
 if (event != null) {
 String eventString = event;
 try {
 //在这里做一些监听到参数的处理,可能会同步通知很多
 // final imMap = json.decode(eventString);
 parseGetStringNotification(eventString);
 //监听到数据之后做各种解析
 } on FormatException catch (e) {
 print(e.message);
 } on NoSuchMethodError catch (e) {
 print(e.toString());
 }
 }
 }
 //错误监听这个不用管
 void _onError(Object error) {
 print(“ZhwLogin - ${error.toString()}”);
 }
 }


7、接下来看下调用

Flutter android studio 扩张插件 flutter开发插件_flutter_05


initState里 做一个EventChannel的监听操作,我有一个监听打印

initPlatfromState里做了监听的调用 也即 getString()方法

8、看下打印日志哦

Flutter android studio 扩张插件 flutter开发插件_Android_06


具体例子可参考:https://github.com/jianibaobei/test_flutter_plugin