0
点赞
收藏
分享

微信扫一扫

【Flutter -- 进阶】Packages

Ad大成 2022-08-01 阅读 57


【Flutter -- 进阶】Packages_android

文章目录

  • ​​1. 简介​​
  • ​​2. Package 类型​​
  • ​​3. 包的使用​​
  • ​​4. 开发插件包(plugin package)​​
  • ​​4.1 实现MethodCallHandler接口​​
  • ​​4.2 完善onMethodCall方法​​
  • ​​4.3 Flutter客户端​​
  • ​​4.4 使用插件​​
  • ​​4.5 发布插件​​

1. 简介

用过Flutter的开发者都知道,Flutter的库是以包(package)的方式来管理,使用​​package​​​可以创建可轻松共享的模块化代码。一个最小的​​package​​包括:

  • 一个​​pubspec.yaml​​​文件:声明了​​package​​的名称、版本、作者等的元数据文件
  • 一个​​lib​​​文件夹:包括包中公开的(public)代码,最少应有一个​​<package-name>.dart​​文件

2. Package 类型

Packages可以包含多种内容:

  • Dart包(​​library package​​​):其中包含一些Flutter特定功能,因此对Flutter框架具有依赖性,仅将用于Flutter,例如​​Fluro​​​包,也就是我们平常说的​​Flutter​​包。
  • 插件包(​​plugin package​​​):当我们说Flutter插件的时候就是指这,一种专用的Dart包,其中包含用Dart代码编写的API,以及针对Android(使用Java或者Kotlin)和/或针对iOS(使用Object-C或者Swift)平台的特定实现,一个具体例子就是​​battery​​插件包。

3. 包的使用

我们在平时中经常使用库,流程是在​​pubspec.yaml​​里声明一个依赖:

path_provider: ^0.4.1
cached_network_image:

这里简单说明一下,之前没有讲解,后来查了一下,​​^x.x.x​​​ 这个是库对应的版本号,​​^0.4.1​​​表示和​​0.4.1​​版本兼容,也可以指定特定的版本:

  • ​0.4.1:特定的版本​
  • ​any:任意版本​
  • ​<0.4.1:小于0.4.4的版本​
  • ​>0.4.1:大于0.4.1的版本​
  • ​<=0.4.1:小于等于0.4.1的版本​
  • ​>=0.4.1:大于等于0.4.1的版本​
  • ​>=0.4.1<=0.5.0:在0.4.1和0.5.0版本之间(包含0.4.1和0.5.0),也可以用<,>​

当添加依赖,使用时把相关的包导入就可使用,就好像导入​​dio​​库:

import 'package:dio/dio.dart';

就可以使用它里面提供的API:

dio_get() async{
try{
Response response;
response = await Dio().get("http://gank.io/api/data/福利/10/1");
if(response.statusCode == 200){
print(response);
}else{
print("error");
}
}catch(e){
print(e);

}

}

4. 开发插件包(plugin package)

下面就简单实现一个​​Toast​​ 的插件包:

  1. 选择​​Flie > New > New FLutter Project​
  2. 在目录面板中选择第二个​​Flutter Plugin​​​,点击​​next​​​,​​Android stdio​​​ 会有显示​​Select "plugin" when exposing an Android or iOS API for develops​
  3. ​Project name​​​填写​​knight_toast_plugin​​​,这个名字随意,但是要防止和​​pub​​上的库名字冲突

看看项目的目录:

【Flutter -- 进阶】Packages_ide_02


主要看四个目录就可以了:

  • android:插件包API的Android端实现
  • example:一个依赖该插件的Flutter应用程序,来说明如何使用它
  • ios:插件包API的iOS端实现
  • lib:Dart包的API,插件的客户端会使用这里实现的接口

项目创建就是一个完整的简单插件例子,这个例子是实现了​​platformVersion​​​。把​​android​​目录打开:

/** KnightToastPlugin */
public class KnightToastPlugin implements MethodCallHandler {
/** Plugin registration. */
public static void registerWith(Registrar registrar) {
final MethodChannel channel = new MethodChannel(registrar.messenger(), "knight_toast_plugin");
channel.setMethodCallHandler(new KnightToastPlugin());
}

@Override
public void onMethodCall(MethodCall call, Result result) {
if (call.method.equals("getPlatformVersion")) {
result.success("Android " + android.os.Build.VERSION.RELEASE);
} else {
result.notImplemented();
}
}
}

发现和一开始使用平台通道编写平台特定的代码很像,从上面知道​​knightToastPlugin​​​这个插件实现了​​MethodCallHandler​​​,先看看这个​​MethodCallHandler​​接口:

//返回结果接口
public interface Result {
//成功
void success(@Nullable Object var1);
//失败
void error(String var1, @Nullable String var2, @Nullable Object var3);
//没有实现接口时回调 通常是调用了未知的方方法
void notImplemented();
}
//处理本地方法的请求接口
public interface MethodCallHandler {
void onMethodCall(MethodCall var1, MethodChannel.Result var2);
}

反正实现一个插件时需要实现这个接口,下面实现弹出吐司这个功能:

4.1 实现MethodCallHandler接口

public class KnightToastPlugin implements MethodCallHandler{

//插件注册
public static void registerWith(Registrar registrar){
//samples.flutter/knight_toast_plugin 这是Method channel的名字 上面是有说过,这里并且添加了域名,为了防止冲突
final MethodChannel channel = new MethodChannel(registrar.messenger(), "samples.flutter/knight_toast_plugin");
channel.setMethodCallHandler(new KnightToastPlugin());

}

@Override
public void onMethodCall(MethodCall methodCall,) {

}
}

因为使用过Toast都知道,Android需要一个上下文环境(Context),把Context参数加上:

private Context mContext;
public KnightToastPlugin(Context mContext){
this.mContext = mContext;
}
//插件注册
public static void registerWith(Registrar registrar){
....
//从Registrar获得context
channel.setMethodCallHandler(new KnightToastPlugin(registrar.context()));

}

4.2 完善onMethodCall方法

@Override
public void onMethodCall(MethodCall methodCall, Result result) {
//首先判断方法名是否为"showToast"
if(methodCall.method.equals("showToast")){
//因为调用原生,只能传递一个参数,如果想要传递多个,那就放在map里,用map传递
//用MethodCall.argument("xxxx")来取值
//显示内容
String message = methodCall.argument("message");
//时间为short 还是 long
String duration = methodCall.argument("duration");
//调用原生弹出吐司
Toast.makeText(mContext,message,duration.equals("length_short") ? Toast.LENGTH_SHORT : Toast.LENGTH_LONG).show;
//成功
result.success(true);
} else {
//没这个方法
result.notImplemented();
}
}

4.3 Flutter客户端

在 FLutter 客户端需要做有两步:

  • 生成一个​​MethodChannel​​,例子已经帮生成了。
  • 通过这个​​MethodChannel​​​调用​​showToast​​方法。

【Flutter -- 进阶】Packages_android_03

import 'dart:async';
import 'package:flutter/services.dart';


enum Duration{
length_short,
length_long
}

class KnightToastPlugin {
//这里要和你在android目录下写的插件通道要对应 new MethodChannel(registrar.messenger(), "samples.flutter/knight_toast_plugin");
static const MethodChannel _channel =
const MethodChannel('samples.flutter/knight_toast_plugin');
// 不需要自带的例子
// static Future<String> get platformVersion async {
// final String version = await _channel.invokeMethod('getPlatformVersion');
// return version;
// }
static Future<bool> showToast(String message,Duration duration) async{
//参数封装
var argument = {'message':message,'duration':duration.toString()};
//这个方法是异步调用 "showToast"对应在上面所写的原生代码的methodCall.method.equals("showToast")
var success = await _channel.invokeMethod('showToast',argument);
return success;
}
}

4.4 使用插件

把​​example > lib​​​目录下的​​main.dart​​修改如下:

import 'package:flutter/material.dart';
import 'package:knight_toast_plugin/knight_toast_plugin.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
_showToast(){
KnightToastPlugin.showToast("吐司出来~", Duration.length_short);
}

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: Text('吐司例子'),
),
floatingActionButton : FloatingActionButton(
onPressed: _showToast,
tooltip: "可以弹出toast",
child: new Icon(Icons.audiotrack)
),
),
);
}
}

效果如下:

【Flutter -- 进阶】Packages_flutter_04

4.5 发布插件

插件功能做出来,下面就等发布了,下面把插件发布到​​pub.dartlang.org​​上,发布需要科学上网。。,检查pubspec.yaml,这里需要补一下基本信息:

​name: knight_toast_plugin​​ ->插件名字

​description: toast_plugin​​ ->插件描述

​version: 0.0.1​​ ->插件版本

​author: kevin0724@163.com​​ ->作者

​homepage: https://github.com/KnightAndroid​​->主页

建议将下面文档添加到插件包:

  • ​README.md​​:结束插件的文件
  • ​CHANGELOG​​:记录每个版本中的更改
  • ​LICENSE​​:包含插件许可条款的文件
  • 【Flutter -- 进阶】Packages_ide_05

检查插件,在根目录执行下面命令,检测插件有没有问题:

flutter packages pub publish --dry-run

如果显示包太大,就把build、.idea删除,并且把一些警告解决,最后输出:

Package has 0 warnings.

下面就可以真正发布插件了,命令如下:

flutter packages pub publish


举报

相关推荐

0 条评论