Flutter入门:applicationmodulepackageplugin

Posted BennuCTech

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter入门:applicationmodulepackageplugin相关的知识,希望对你有一定的参考价值。

我们用AS创建flutter项目时,会看到几个选项:application、module、package、plugin。

application

就是一个新flutter app,这个没什么可说的

module

androidios项目中添加一个flutter模块。 这个的作用是在原有的项目中使用flutter,不改变原项目结构。所以说这个并不是在flutter项目使用的。

package

package和plugin都是可以发布到pub仓库的,可以说是公开的通用库。区别是package是纯dart的,而plugin是包括android和ios的。

plugin

当我们引用plugin到自己的项目里,打包的时候就会将其下的android和ios相关代码和文件与主项目里对应的平台代码合并到一起。

plugin也可以不发布到pub仓库,在本地直接引用。

比如我们在一个项目里new -> module -> flutter plugin,创建一个名为flutter_core的plugin,这时候我们只要在pubspec.yaml中添加

dependencies:
  flutter:
    sdk: flutter

  ...
  flutter_core:
    path: flutter_core

这样就可以将plugin依赖进来使用了

plugin中android代码编译问题

但是,上面这样还有一个问题,plugin下的android目录在本项目里无法按android来编译,所以在编写android代码时没有任何补全和错误提示。

我的解决方法是不以moudle形式创建,而在项目中创建一个plugins目录,然后new -> new flutter project -> flutter plugin,以项目的形式创建一个plugin,而这个plugin的项目路径选在新创建的plugins目录下。

在该项目中,这个plugin中的android目录还是无法按android编译,但是我们可以单独打开这个plugin的工程,这样就正常编译了。

而在主项目中,这个plugin会被自动识别的,所以我们只要修改依赖即可

dependencies:
  flutter:
    sdk: flutter

  ...
  flutter_core:
    path: plugins/flutter_core

plugin中kotlin编译问题

上面我们以工程的方式打开plugin,其下的android代码就可以正常编译使用了。但是还有另外一个问题,我们发现kotlin还无法编译使用,也就是或kotlin标准的api,比如let函数找不到,直接报错。

经过对比发现在plugin的根目录下的.idea/libraries目录下缺少KotlinJavaRuntime.xml这个文件。这个文件在pliugin的example项目中有,可以拷贝一份过来

然后重新打开plugin的工程,发先kotlin代码可以正常编译使用了。

添加前,在依赖列表External Libraries中 image 没有KotlinJavaRuntime,添加后就出现了,这样我们才可以使用kotlin标准库

plugin中android代码如何获得context?

plugin的作用就是有原生实现一个功能,然后与flutter进行交互。

那么在plugin中要实现一个安卓的功能,不可避免的需要用到Context,因为很大一部分android api都需要它。

但是在plugin中,因为入口不是activity也是application,那么这个context我们怎么获取?

我们创建plugin后,会看到在其下的Android目录中自动创建了一个类

public class XXXX: FlutterPlugin, MethodCallHandler 
  override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) 
    val channel = MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "flutter_xxx")
    channel.setMethodCallHandler(XXXX());
  

  companion object 
    @JvmStatic
    fun registerWith(registrar: Registrar) 
      val channel = MethodChannel(registrar.messenger(), "flutter_xxx")
      channel.setMethodCallHandler(XXXX())
    
  

  override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) 
    when(call.method)
      "getPlatformVersion" -> result.success("Android $android.os.Build.VERSION.RELEASE")
      else -> result.notImplemented()
    
  

  override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) 
  

这个类继承FlutterPlugin这个抽象类,实现了onAttachedToEngine这个函数,通过函数名可以知道它会最开始执行。

它的参数是FlutterPlugin.FlutterPluginBinding,这个对象里就有我们需要的context,我们可以新建一个static变量来保存它,如下

public class XXXX: FlutterPlugin, MethodCallHandler 
  override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) 
    mContext = flutterPluginBinding.applicationContext
    ...
  

  companion object 
    var mContext : Context? = null
    ...
  

  ...

这样我们在plugin中就可以随时使用context了。

关注公众号:BennuCTech,获取更多干货!

以上是关于Flutter入门:applicationmodulepackageplugin的主要内容,如果未能解决你的问题,请参考以下文章

Flutter之beamer路由入门指南

Flutter 开发入门实践

和我一起入门Flutter -- 初识Flutter

Flutter入门:在macOS中安装Flutter

Flutter 入门和教程导航

Flutter基础系列之入门