Day12 开发插件 - 范例程序码介绍01 Flutter 端

官方推荐的做法是使用cmd 来创建,可以去官方文件参考,这边我来用Android Studio 来开发插件,以做一个获得设备电池电量资讯的插件示范,顺便对Flutter 的三种Platform Channel 做些实作范例

首先在Android Studio 上新增Flutter 专案

https://ithelp.ithome.com.tw/upload/images/20210927/201184796YEpLtGioI.png

选择Plugin 後按下一步

https://ithelp.ithome.com.tw/upload/images/20210927/20118479BAfH9lRfGW.png

输入您的专案名称後,选择要使用的平台原生程序语言後完成

https://ithelp.ithome.com.tw/upload/images/20210927/20118479WrB5qJnyNL.png

建立完成後我们来看看整个plugin 项目的结构

https://ithelp.ithome.com.tw/upload/images/20210927/201184797m9XJtPL0B.png

这边我们先介绍其中几个内容:

  • lib
    这是plugin package 中,Dart API 的程序码,主要为了API 的功能实现,建立专案时会自动生成一个以专案名称命名的.dart,供使用者在自己的flutter 专案中调用的接口代码

  • android

    负责实现plugin package 中的Android 平台的功能实现,会与lib里的接口配合进行功能开发

  • ios

    负责实现plugin package 中的iOS 平台的功能实现,会与lib里的接口配合进行功能开发

  • example

    这是用来说明使用者如何在自己的flutter 专案中使用plugin package 的范例专案,此专案已经依赖我们的plugin package

MethodChannel

其中Android Studio 在建立时,就会生成一个用MethodChannel来获取平台现在的版本的功能实现范例,我们先来看看是怎麽实现这个功能的

首先我们来看Flutter 端:

lib/batterylevel.dart

class Batterylevel {
  static const MethodChannel _channel =
      const MethodChannel('batterylevel');

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

预设已在Flutter 端建立MethodChannel来呼叫Native 端的方法(预设MethodChannel 的名称为专案名,且使用的所有通道名称都不能重复),其通道的两端,Native 端和Flutter 端会通过这个MethodChannel进行连接(故两端使用的MethodChannel名称需要相对应)

接下来预设建立的还有platformVersiongetter,会以非同步方式来对MethodChannel呼叫invokeMethod方法并传入方法名来呼叫原生端对应的方法以获取平台版本资讯

接着来看Native 端(Android):

预设建立的android/.../BatterylevelPlugin.kt

class BatterylevelPlugin: FlutterPlugin, MethodCallHandler {
  /// The MethodChannel that will the communication between Flutter and native Android
  ///
  /// This local reference serves to register the plugin with the Flutter Engine and unregister it
  /// when the Flutter Engine is detached from the Activity
  private lateinit var channel : MethodChannel

  override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
    channel = MethodChannel(flutterPluginBinding.binaryMessenger, "batterylevel")
    channel.setMethodCallHandler(this)
  }

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

  override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
    channel.setMethodCallHandler(null)
  }
}

这边用来实现Native 端(Android)的功能,首先会实作**FlutterPluginMethodCallHandler**接口

  1. 实作FlutterPlugin接口,必须实作onAttachedToEngine以及onDetachedFromEngine方法
    • onAttachedToEngine:插件被FlutterEngine加载时调用,可以做一些初始化工作,预设已在这边设置好MethodChannel的通道名称(需要与Flutter 端使用的MethodChannel名称相对应),并通过MethodChannel呼叫setMethodCallHandler来注册一个MessageHandler来接收此通道讯息,设定为this是因为BatterylevelPlugin已实作MethodCallHandler接口,所以能够处理接收通道的讯息
    • onDetachedFromEngine:插件从FlutterEngine移除时调用,可以做一些清理工作,这边对MethodChannel呼叫setMethodCallHandler设定为null,将此通道进行注销
  2. 实作MethodCallHandler接口,就必须实作onMethodCall,目的可让MethodChannel调用setMethodCallHandler,实现从Flutter 端要调用的原生方法,这边对Flutter 端呼叫的方法getPlatformVersion做功能的实现,当Flutter 端呼叫此方法,就会回传现在Android 的版本资讯回去

<<:  Day12 SwiftUI 05 - Life Cycle - SwiftUI App

>>:  Angular 深入浅出三十天:表单与测试 Day12 - 单元测试实作 - 被保人 by Template Driven Forms

Day 21 - Robot Return to Origin

大家好,我是毛毛。ヾ(´∀ ˋ)ノ 废话不多说开始今天的解题Day~ 657. Robot Retu...

DAY1 机器学习(ML)、深度学习(DL)与NLP

什麽是机器学习? 机器学习是一种能够赋予机器学习的能力,以让机器完成直接编程所无法完成的任务的方法。...

Python 搜寻子目录下档案+筛选条件 walk+fnmatch

Python os.walk 找档案很容易,可是 天坑 也不少。逐行注解、测试,才不会搞迷糊了。 延...

Laravel - jQuery AJAX 范例

最近满常要把一般 form-submit 改成 AJAX 非同步去送表单,所以分享个 templat...

【D7】取得历史资料:三大法人-区分期货与选择权二类

前言 在昨日取得的资料仅有当天的资讯,政府有提供下载近三年的资料,更多就需要申请,不过我们这三年已经...