用Flutter开发自定义Plugin的方法示例
作者:zyangdev 发布时间:2023-07-05 00:19:40
当你在开发flutter应用的时候,有时会需要调用native的api,往往遇到flutter并没有相应的package, 这时候flutter plugin就开始发挥作用了,这篇文章将会讲解开发一个简单flutter plugin的步骤和方法,好了,让我们开始动手吧。
1.在Android Studio 中创建一个Flutter Plugin 项目,如下图
上图中你能看到项目描述中写到,如果需要暴露Andorid或iOS的API给开发者时,选择"Plugin"项目类型。
这个项目我们命名为:flutter_native_log_plugin, 当我们完成创建项目后,有两个文件我们需要看一看, 一个是位于android/src下的FlutterNativeLogPlugin.java, 这段代码是用来和本地设备交互,然后将交互结果返回供flutter前端调用, 如下所示:
package com.cube8.flutter_native_log_plugin;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry.Registrar;
/** FlutterNativeLogPlugin */
public class FlutterNativeLogPlugin implements MethodCallHandler {
/** Plugin registration. */
public static void registerWith(Registrar registrar) {
final MethodChannel channel = new MethodChannel(registrar.messenger(),
"flutter_native_log_plugin");
channel.setMethodCallHandler(new FlutterNativeLogPlugin());
}
@Override
public void onMethodCall(MethodCall call, Result result) {
if (call.method.equals("getPlatformVersion")) {
result.success("Android " + android.os.Build.VERSION.RELEASE);
} else {
result.notImplemented();
}
}
}
另一个 /lib/mian.dart文件,这段代码是主要用来和native代码交互, 如下所示:
import 'dart:async';
import 'package:flutter/services.dart';
class FlutterNativeLogPlugin {
static const MethodChannel _channel =
const MethodChannel('flutter_native_log_plugin');
static Future<String> get platformVersion async {
final String version = await _channel.invokeMethod('getPlatformVersion');
return version;
}
}
2.现在我们开始编写我们的Plugin.
在lib/flutter_native_log_plugin.dart 文件中,我们先创建一个新的方法,代码如下:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
enum Log { DEBUG, WARNING, ERROR }
class FlutterNativeLogPlugin {
static const MethodChannel _channel =
const MethodChannel('flutter_native_log_plugin');
static Future<String> printLog(
{Log logType, @required String tag, @required String msg}) async {
String log = "debug";
if (logType == Log.WARNING) {
log = "warning";
} else if (logType == Log.ERROR) {
log = "error";
} else {
log = "debug";
}
final Map<String, dynamic> params = <String, dynamic>{
'tag': tag,
'msg': msg,
'logType': log
};
final String result = await _channel.invokeMethod('printLog', params);
return result;
}
}
在Android端,我们将android/src下的FlutterNativePlugin.java改写如下:
package com.cube8.flutter_native_log_plugin;
import android.util.Log;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry.Registrar;
/**
* FlutterNativeLogPlugin
*/
public class FlutterNativeLogPlugin implements MethodCallHandler {
/**
* Plugin registration.
*/
public static void registerWith(Registrar registrar) {
final MethodChannel channel = new MethodChannel(registrar.messenger(), "flutter_native_log_plugin");
channel.setMethodCallHandler(new FlutterNativeLogPlugin());
}
@Override
public void onMethodCall(MethodCall call, Result result) {
if (call.method.equals("printLog")) {
String msg = call.argument("msg");
String tag = call.argument("tag");
String logType = call.argument("logType");
if (logType.equals("warning")) {
Log.w(tag, msg);
} else if (logType.equals("error")) {
Log.e(tag, msg);
} else {
Log.d(tag, msg);
}
result.success("Logged Successfully!");
} else {
result.notImplemented();
}
}
}
3.测试plugin。当开发完了我们的plugin之后,我们需要测试这个新plugin是否可用,于是对example/lib的main.dart文件作如下修改:
import 'package:flutter/material.dart';
import 'package:flutter_native_log_plugin/flutter_native_log_plugin.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
}
void printLogs() async {
print(await FlutterNativeLogPlugin.printLog(
tag: "Debug", msg: "This is ordinary Log")); // default logType
print(await FlutterNativeLogPlugin.printLog(
tag: "Debug",
msg: "This is warning Log",
logType: Log.WARNING)); // logType = warning
print(await FlutterNativeLogPlugin.printLog(
tag: "Debug",
msg: "This is error Log",
logType: Log.ERROR)); // logType = error
print(await FlutterNativeLogPlugin.printLog(
tag: "Debug",
msg: "This is debug Log",
logType: Log.DEBUG)); // logType = debug
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: RaisedButton(
child: Text("PrintLogs"),
onPressed: printLogs,
),
),
),
);
}
}
点击app中的按钮,控制台将看到如下输出,说明plugin可以顺利运行了。
4.最后一步就是将我们开发的plugin发布到dart pub供以后直接调用。打开控制台,需要确认定位到plugin项目的根目录,然后输入如下命令:
flutter packages pub publish --dry-run
这段命令会做一个程序相关文件和信息的检查,确保待发布的plugin信息完整,根据控制台的提示完善信息后,与下图相似:
接着输入如下命令,正式将plugin发布到dart pub中:
flutter packages pub publish
来源:https://segmentfault.com/a/1190000019488195
猜你喜欢
- 在观察者模式中有2个要素:一个是被观察对象,另一个是观察者。但被观察对象的状态发生改变会通知观察者。举例:把订阅报纸的人看作是观察者,把报纸
- 前言为什么用动静态库我们在实际开发中,经常要使用别人已经实现好的功能,这是为了开发效率和鲁棒性(健壮性);因为那些功能都是顶尖的工程师已经写
- .c 源程序 ----- 编译 ----- 链接 ---- exe ----运行 -------->程序翻译环境和执行环境翻译环境:源
- 本文实例为大家分享了Struts2框架拦截 器实例的示例代码,供大家参考,具体内容如下在看拦截 器的小例子的前我们先来看看sturts2的原
- 在谈 JVM 内存区域划分之前,我们先来看一下 Java 程序的具体执行过程,我画了一幅图。Java 源代码文件经过编译器编译后生成字节码文
- 介绍Spring Cache是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。Spring Cache提供了一
- 在类中自定义的“函数”称为“方法”,由于C#是完全面向对象的
- forward_list 概述forward_list 是 C++ 11 新增的容器,它的实现为单链表。forward_list 是支持从容
- 模拟登陆的原理很简单,就是发送一个Http 请求服务器获得响应,然后客户端获取到cookie即可实现模拟登陆,比如一些抢票软件的原理无非也是
- 参考:How to catch an Exception from a threadIs there a way to make Runna
- 近日于LeetCode看题遇1114 按序打印,获悉一解法使用了Semaphore,顺势研究,记心得于此。此解视Semaphore为锁,以保
- 光流的概念是由一个叫Gibson的哥们在1950年提出来的。它描述是空间运动物体在观察成像平面上的像素运动的瞬时速度,利用图像序列中像素在时
- 本文实例讲述了C#创建临时文件的方法。分享给大家供大家参考。具体分析如下:C#可以通过Path.GetTempFileName获得一个临时文
- Console.WriteLine("This is a Client, host name is {0}", Dns.
- 最近在研究android自定义控件属性,学到了TypedArray以及attrs。大家也可以结合《理解Android中的自定义属性》这篇文章
- 因为mybatis好使,所以几乎需要操作数据库的时候,我都会使用mybatis,而且在一个正式的项目中,同时存在BS和CS的程序,都使用的M
- 什么是JMMJMM全称Java Memory Model, 中文翻译Java内存模型,一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问
- 你知道String、StringBuilder、Stringbuffer的区别吗?当你创建字符串的时候,有考虑过该使用哪个吗?别急,这篇文章
- 一、百度百科Sentinel 是面向分布式服务架构的高可用流量防护组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防
- 很多时候我们开发的软件需要向用户提供软件参数设置功能,例如我们常用的QQ,用户可以设置是否允许陌生人添加自己为好友。对于软件配置参数的保存,