首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Kotlin/Native 用KMM写Flutter插件

Kotlin/Native 用KMM写Flutter插件

原创
作者头像
libill
修改于 2021-10-29 01:53:29
修改于 2021-10-29 01:53:29
1.1K0
举报
文章被收录于专栏:libilllibill

一、用KMM写Flutter插件

Google官方有一个写Flutter例子How to write a Flutter plugin,这里把Google plugin_codelab 例子改成用KMM写Flutter插件。

二、如何运行

Github项目地址:kmm-flutter-plugin

Android: run shared/plugin_codelab/example/android

iOS:

1、build shared.framework

代码语言:txt
AI代码解释
复制
use ./gradlew releaseIOSFramework
or use new version Android Studio sync

2、run shared/plugin_codelab/example/ios

Tips: before run,shared/build/cocoapods/framework/shared.framework should be generated. The shared.h header file shared/build/cocoapods/framework/shared.framework/Headers/shared.h is generated.

三、设计思路

Android/iOS插件PluginCodelabPlugin只需要实现KMM Module的接口,不写任何逻辑,把逻辑通过接口放在KMM Module中。

1、定义接口中间层用于转发数据

如参考Flutter插件的MethodCall、MethodChannel,定义CommonMethodCall数据类、CommonMethodChannel.Result接口。

代码语言:txt
AI代码解释
复制
data class CommonMethodCall(
    val method: String,
    val arguments: Any?,
)

class CommonMethodChannel {
    interface Result {
        fun success(result: Any?)

        fun error(errorCode: String?, errorMessage: String?, errorDetails: Any?)

        fun notImplemented()
    }
}
2、在KMM中的commonMain实现CommonCodelabPlugin插件的公共逻辑

CommonCodelabPlugin需要初始化并启动synth?.start(),处理getPlatformVersion、onKeyDown、onKeyUp逻辑。

代码语言:txt
AI代码解释
复制
class CommonCodelabPlugin {

    private val synth = Synth()

    init {
        synth?.start()
    }

    fun onMethodCall(call: CommonMethodCall, result: CommonMethodChannel.Result) {
        when (call.method) {
            "getPlatformVersion" -> {
                result.success(Platform().platform)
            }
            "onKeyDown" -> {
                try {
                    val arguments = call.arguments as List<*>
                    val numKeysDown = synth?.keyDown((arguments[0] as Int))
                    result.success(numKeysDown)
                } catch (ex: Exception) {
                    result.error("1", ex.message, ex.cause)
                }
            }
            "onKeyUp" -> {
                try {
                    val arguments = call.arguments as List<*>
                    val numKeysDown = synth?.keyUp((arguments[0] as Int))
                    result.success(numKeysDown)
                } catch (ex: Exception) {
                    result.error("1", ex.message, ex.cause)
                }
            }
            else -> {
                result.notImplemented()
            }
        }
    }
}

还有包括插件名称也属于公共逻辑

代码语言:txt
AI代码解释
复制
// 插件Channel名称
const val PLUGIN_CODE_LAB_CHANNEL = "plugin_codelab"
3、实现平台差异特性

这里只列出expect接口,具体实现平台差异特性类请查看源码

代码语言:txt
AI代码解释
复制
expect class Synth() {
    fun start()

    fun keyDown(key: Int): Int

    fun keyUp(key: Int): Int
}

expect class Platform() {
    val platform: String
}
4、Android Flutter实现插件KMM接口

Android Flutter实现插件KMM接口,注意这里只实现接口用于中转Flutter与Android/iOS 数据,不能有任何业务逻辑

代码语言:txt
AI代码解释
复制
class PluginCodelabPlugin : FlutterPlugin, MethodCallHandler {
    private var channel: MethodChannel? = null
    private var commonCodelabPlugin: CommonCodelabPlugin? = null

    override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
        setup(this, flutterPluginBinding.binaryMessenger)
    }

    override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
        commonCodelabPlugin?.onMethodCall(
            call = CommonMethodCall(call.method, call.arguments),
            result = object : CommonMethodChannel.Result {
                override fun success(successResult: Any?) {
                    result.success(successResult)
                }

                override fun error(errorCode: String?, errorMessage: String?, errorDetails: Any?) {
                    result.error(errorCode, errorMessage, errorDetails)
                }

                override fun notImplemented() {
                    result.notImplemented()
                }
            })
    }

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

    companion object {
        private fun setup(plugin: PluginCodelabPlugin, binaryMessenger: BinaryMessenger) {
            plugin.channel = MethodChannel(binaryMessenger, PLUGIN_CODE_LAB_CHANNEL)
            plugin.channel?.setMethodCallHandler(plugin)
            plugin.commonCodelabPlugin = CommonCodelabPlugin()
        }
    }
}
5、iOS Flutter实现插件KMM接口

Android Flutter实现插件KMM接口,注意这里只实现接口用于中转Flutter与Android/iOS 数据,不能有任何业务逻辑

代码语言:txt
AI代码解释
复制
#import "PluginCodelabPlugin.h"

@implementation PluginCodelabPlugin{
  int _numKeysDown;
  FlutterResult _flutterResult;
  SharedCommonCodelabPlugin* _codelabPlugin;
}

- (instancetype)init {
  self = [super init];
  if (self) {
    // create music
    _codelabPlugin = [[SharedCommonCodelabPlugin alloc] init];
  }
  return self;
}

- (void)dealloc {
    // destroy music
}

+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
  FlutterMethodChannel* channel = [FlutterMethodChannel
      methodChannelWithName: SharedPluginCodeLabKt.PLUGIN_CODE_LAB_CHANNEL
            binaryMessenger:[registrar messenger]];
  PluginCodelabPlugin* instance = [[PluginCodelabPlugin alloc] init];
  [registrar addMethodCallDelegate:instance channel:channel];
}

- (void)handleMethodCall:(FlutterMethodCall *)call
                  result:(FlutterResult)result {
    SharedCommonMethodCall *methodCall = [[SharedCommonMethodCall alloc] initWithMethod:call.method arguments:call.arguments];
    _flutterResult = result;
    [_codelabPlugin onMethodCallCall:methodCall result:self ];
}

- (void)errorErrorCode:(NSString * _Nullable)errorCode errorMessage:(NSString * _Nullable)errorMessage errorDetails:(id _Nullable)errorDetails {
    NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain code:errorCode.intValue userInfo:@{@"errorMessage":errorMessage, @"errorDetails":errorDetails}];
    if (_flutterResult) {
        _flutterResult(error);
    }
}

- (void)notImplemented {
    if (_flutterResult) {
        _flutterResult(FlutterMethodNotImplemented);
    }
}

- (void)successResult:(id _Nullable)result {
    if (_flutterResult) {
        _flutterResult(result);
    }
}

@end

到这里,已经完成了使用KMM开发一个Flutter插件。使用KMM开发插件的好处是公共逻辑都使用kotlin写,一般公共逻辑比较简单适合使用kotlin写,便于维护。而且,实现了KMM写插件,Flutter写UI

四、参考链接

本文地址:https://www.cnblogs.com/liqw/p/15477079.html

Github项目地址:kmm-flutter-plugin

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
数据科学 IPython 笔记本 7.10 组合数据集:合并和连接
Pandas 提供的一个基本特性,是内存中的高性能的连接和合并操作。如果你曾经使用过数据库,那么你应该熟悉这种类型的数据交互。它的主要接口是pd.merge函数,我们将看到几个在实践中如何工作的例子。
ApacheCN_飞龙
2022/06/03
1.1K0
Python自动化办公之Excel对比工具
今天我们继续分享真实的自动化办公案例,希望各位 Python 爱好者能够从中得到些许启发,在自己的工作生活中更多的应用 Python,使得工作事半功倍!
周萝卜
2022/04/06
9900
Python自动化办公之Excel对比工具
用 Python 帮财务小妹对比 Excel,小妹这次破防了。。。
由于工作当中经常需要对比前后两个Excel文件,文件内容比较多,人工肉眼对比太费劲,还容易出错,搞个Python小工具,会不会事半功倍
周萝卜
2021/11/08
5740
ElasticSearch 索引查询使用指南——详细版
  绿色表示一切正常, 黄色表示所有的数据可用但是部分副本还没有分配,红色表示部分数据因为某些原因不可用.
双面人
2019/04/10
3.8K0
ElasticSearch 索引查询使用指南——详细版
《Pandas Cookbook》第04章 选取数据子集1. 选取Series数据2. 选取DataFrame的行3. 同时选取DataFrame的行和列4. 用整数和标签选取数据5. 快速选取标量6
第01章 Pandas基础 第02章 DataFrame运算 第03章 数据分析入门 第04章 选取数据子集 第05章 布尔索引 第06章 索引对齐 第07章 分组聚合、过滤、转换 第08章 数据清理 第09章 合并Pandas对象 第10章 时间序列分析 第11章 用Matplotlib、Pandas、Seaborn进行可视化
SeanCheney
2018/10/10
3.8K0
天池大数据竞赛 Spaceack带你利用Pandas,趋势图与桑基图分析美国选民候选人喜好度
首先,这是一篇面向新人的教程导向的分析文章,(by the way其实我也是新手,从比赛开始才学的Pandas库,这也是我的一篇学习笔记),所以会包含很多函数的基础用法,解题思路等等, 流程会比较详细。
Spaceack
2021/01/05
1K0
不平衡数据集分类实战:成人收入数据集分类模型训练和评估
一个常用的例子是成人收入数据集,它涉及到社交关系、教育水平等个人数据,以此来预测成人的收入水平,判断其是否拥有5万美元/年的个人收入。数据集中个人收入低于5万美元的数据比高于5万美元的数据要明显多一些,存在着一定程度的分布不平衡。 针对这一数据集,可以使用很多不平衡分类的相关算法完成分类任务。
deephub
2020/05/09
2.4K0
不平衡数据集分类实战:成人收入数据集分类模型训练和评估
Python连接MIMIC-IV数据库并图表可视化
这种直接SQL提取方式很直接,但是不是最好的方式也不利于数据的进一步统计分析、可视化和预测分析, 所以我们这里讲解下:
科研收录
2023/12/12
4370
Python连接MIMIC-IV数据库并图表可视化
ElasticSearch初体验
构建在开源基础之上, Elastic Stack 让您能够安全可靠地获取任何来源、任何格式的数据,并且能够实时地对数据进行搜索、分析和可视化
小旋锋
2019/01/21
1.1K0
数据缺失、混乱、重复怎么办?最全数据清洗指南让你所向披靡
在拟合机器学习或统计模型之前,我们通常需要清洗数据。用杂乱数据训练出的模型无法输出有意义的结果。
机器之心
2020/04/22
2.9K0
数据缺失、混乱、重复怎么办?最全数据清洗指南让你所向披靡
《Pandas Cookbook》第02章 DataFrame基本操作1. 选取多个DataFrame列2. 对列名进行排序3. 在整个DataFrame上操作4. 串联DataFrame方法5. 在
In[1]: import pandas as pd import numpy as np pd.options.display.max_columns = 40 1. 选取多个DataFrame列 # 用列表选取多个列 In[2]: movie = pd.read_csv('data/movie.csv') movie_actor_director = movie[['actor_1_name', 'actor_2_name', 'actor_3_name
SeanCheney
2018/10/10
4.9K0
《Pandas Cookbook》第02章 DataFrame基本操作1. 选取多个DataFrame列2. 对列名进行排序3. 在整个DataFrame上操作4. 串联DataFrame方法5. 在
Elasticsearch7.6学习笔记1 Getting start with Elasticsearch
安装方法见: https://www.cnblogs.com/woshimrf/p/docker-es7.html
Ryan-Miao
2020/04/12
1.7K0
将文本特征应用于客户流失数据集
在我的上一篇博客“什么是嵌入,你能用它做什么”中,我谈到了嵌入可以把高维、非结构化的数据转换成低维的数值表示,可以用在各种机器学习模型中。
磐创AI
2021/09/03
1K0
用 Pandas 进行数据处理系列 二
获取行操作df.loc[3:6]获取列操作df['rowname']取两列df[['a_name','bname']] ,里面需要是一个 list 不然会报错增加一列df['new']=list([...])对某一列除以他的最大值df['a']/df['a'].max()排序某一列df.sorted_values('a',inplace=True,ascending=True) , inplace 表示排序的时候是否生成一个新的 dataFrame , ascending=True 表示升序,默认为升序,如果存在缺失的补值( Nan ),排序的时候会将其排在末尾
zucchiniy
2019/10/30
8.6K0
如何使用方差阈值进行特征选择
今天,数据集拥有成百上千个特征是很常见的。从表面上看,这似乎是件好事——每个样本的特征越多,信息就越多。但通常情况下,有些特征并没有提供太多价值,而且引入了不必要的复杂性。
deephub
2021/04/16
2.3K0
ElasticSearch
​ 保存在某个index下,某种type的一个数据document,文档是json格式的,document就像是mysql中的某个table里面的内容。每一行对应的列叫属性
OY
2022/03/20
1.3K0
ElasticSearch
COVID-19数据分析实战:数据清洗篇
2020 年全球的关键词非COVID19 莫属。虽然现在关于病毒的起源众说纷纭,也引起了不小的外交冲突。作为数据爱好者,还是用数据说话比较靠谱。
Ai学习的老章
2020/05/25
1.4K0
COVID-19数据分析实战:数据清洗篇
利用 Python 分析 MovieLens 1M 数据集
MovieLens数据集是一个关于电影评分的数据集,里面包含了从IMDB, The Movie DataBase上面得到的用户对电影的评分信息,详细请看下面的介绍。
JavaEdge
2022/11/30
1.8K0
利用 Python 分析 MovieLens 1M 数据集
一文搞懂:什么是Stacking堆叠?手把手带你搭建堆叠模型,附有python源码和数据集。
在该文章采用的是Lightgbm模型进行的分类预测,本次分享一个在竞赛中常用的策略,堆叠。
机器学习司猫白
2025/01/21
6540
一文搞懂:什么是Stacking堆叠?手把手带你搭建堆叠模型,附有python源码和数据集。
数据科学的原理与技巧 四、数据清理
数据以多种格式出现,并且在分析的实用性方面差别很大。尽管我们希望,我们所有的数据都以表格的形式出现,并且每个数值的记录都一致和准确,但实际上,我们必须仔细检查数据,找出最终可能导致错误结论的潜在问题。
ApacheCN_飞龙
2022/12/01
9640
推荐阅读
相关推荐
数据科学 IPython 笔记本 7.10 组合数据集:合并和连接
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档