Flutter 通过本地文件引用package和plugin
前言
在文章一步步实现一个Flutter plugin插件中我们介绍了如何创建一个插件plugin,在创建的项目中有默认为我们创建了一个测试项目,直接引用了该plugin,可以直接运行。
但是如果我们创建的项目不仅仅该测试项目使用,在其他项目中也要使用呢,创建插件的目的不也是要在多个项目中共享该插件的功能吗。Flutter官方介绍了三种方法
- 上传到Pub site,这是一个类似Maven的Dart仓库。
- 上传到Git,通过Git引用
- 本地文件引用
本地引用
首先打开或者新建一个要引用插件的项目
然后打开pubspec.yaml文件,如下所示,我们配置了对plugin_version插件的引用,path后的内容表示插件项目的本地目录,比如我创建的plugin_version的本地存放目录是D:\ws\plugin_version
dev_dependencies:
flutter_test:
sdk: flutter
plugin_version:
path: D:\ws\plugin_version
配置完对插件的引用后,点击pubspec.yaml编辑页顶部的Package get安装插件
在如下路径有一个自动生成的GeneratedPluginRegistrant类,里面会自动生成对对插件PluginVersionPlugin的导入和注册
自动生成的GeneratedPluginRegistrant代码如下
package io.flutter.plugins;
import io.flutter.plugin.common.PluginRegistry;
import com.himmy.plugin_version.PluginVersionPlugin;
/**
* Generated file. Do not edit.
*/
public final class GeneratedPluginRegistrant {
public static void registerWith(PluginRegistry registry) {
if (alreadyRegisteredWith(registry)) {
return;
}
PluginVersionPlugin.registerWith(registry.registrarFor("com.himmy.plugin_version.PluginVersionPlugin"));
}
private static boolean alreadyRegisteredWith(PluginRegistry registry) {
final String key = GeneratedPluginRegistrant.class.getCanonicalName();
if (registry.hasPlugin(key)) {
return true;
}
registry.registrarFor(key);
return false;
}
}
GeneratedPluginRegistrant代码中PluginVersionPlugin类的导入和注册是报红的,这个不用在意,以为这代码是自动生成的,可以正常运行,registry.registrarFor传入的是PluginVersionPlugin类的完整路径,我猜测是通过反射来完成注册的
MainActivity中的代码是自动生成的,里面的onCreate方法中调用GeneratedPluginRegistrant.registerWith完成对所有插件的注册,若无这句话,可以自己添加下
完成插件的引用和注册后,就可以在Dart代码中使用插件了,下面是具体的使用,页面很简单,直接调用插件的PluginVersion.platformVersion方法获取设备Android版本号,然后显示在页面正中间。
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:plugin_version/plugin_version.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _platformVersion = 'Unknown';
@override
void initState() {
super.initState();
initPlatformState();
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
String platformVersion;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
platformVersion = await PluginVersion.platformVersion;
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
setState(() {
_platformVersion = platformVersion;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: Text('Running on: $_platformVersion\n'),
),
),
);
}
}
参考