前言
在开发 Flutter 的 Android 插件时,你是否也遇到过这样的烦恼:在 Android Studio 中打开项目后,总是提示找不到 import io.flutter.xxx
包?虽然我们可以通过创建一个 resolve_flutter_depends.gradle
文件来解决这个问题,并在 build.gradle
中引用它,但这种方式比较笨拙,需要每个项目手动设置,非常不便。
实际上,我们可以利用 Gradle 插件来实现 Flutter 依赖的自动化配置,减少重复操作,提高开发效率。本文将介绍如何创建一个 Gradle 插件并发布到Maven仓库, 用于自动解决 Flutter Android 插件开发中的依赖问题。
创建 Gradle 插件
首先,我们来创建一个 Gradle 插件工程:
shell代码解读复制代码mkdir gradle_plugin_flutter_depends cd gradle_plugin_flutter_depends gradle init
在 gradle init
过程中,可以选择项目类型为 library。其它的看你自己的需要选择, 下图是我的选择:
插件项目
在项目的 build.gradle
文件中进行如下配置:
gradle代码解读复制代码plugins { id 'java-library' id 'java-gradle-plugin' // 添加 Gradle 组件 } apply from: 'maven-push.gradle' // 插件发布配置,后面会讲到 repositories { mavenCentral() google() } dependencies { // Gradle 相关 API implementation gradleApi() implementation localGroovy() } gradlePlugin { plugins { create("FlutterGradle") { // 插件名称 id = "pharos.flutter.dependencies" // 插件 ID implementationClass = "com.e.g.flutter_gradle.FlutterDependenciesPluginPlugin" // 插件实现类 } } }
实现 Flutter 依赖插件功能
接下来,我们编写插件的功能实现类:
java 代码解读复制代码package com.e.g.flutter_gradle;
import org.gradle.api.Project;
import org.gradle.api.Plugin;
import org.gradle.api.artifacts.dsl.RepositoryHandler;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.Properties;
public class FlutterDependenciesPluginPlugin implements Plugin {
public void apply(Project project) {
// 加载 local.properties 文件
Properties localProperties = new Properties();
File localPropertiesFile = project.getRootProject().file("local.properties");
if (localPropertiesFile.exists()) {
try (FileInputStream fis = new FileInputStream(localPropertiesFile)) {
localProperties.load(fis);
} catch (IOException e) {
throw new RuntimeException("Failed to load local.properties file", e);
}
}
// 获取 Flutter SDK 路径
String flutterRootPath = localProperties.getProperty("flutter.sdk");
if (flutterRootPath == null) {
throw new IllegalStateException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.");
}
String[] storageUrl = {System.getenv("FLUTTER_STORAGE_BASE_URL")};
if (storageUrl[0] == null) {
storageUrl[0] = "https://storage.flutter-io.cn";
}
// 配置仓库
RepositoryHandler repositories = project.getRepositories();
repositories.google();
repositories.mavenCentral();
repositories.maven(repo -> repo.setUrl(storageUrl[0] + "/download.flutter.io"));
// 获取引擎版本
File engineVersionFile = Paths.get(flutterRootPath, "bin", "internal", "engine.version").toFile();
String engineVersion;
try {
engineVersion = new String(java.nio.file.Files.readAllBytes(engineVersionFile.toPath())).trim();
} catch (IOException e) {
throw new RuntimeException("Failed to read engine version", e);
}
// 添加依赖
project.afterEvaluate(evaluatedProject -> {
if (evaluatedProject.getConfigurations().findByName("releaseImplementation") != null) {
evaluatedProject.getDependencies().add("releaseImplementation", "io.flutter:flutter_embedding_release:1.0.0-" + engineVersion);
evaluatedProject.getDependencies().add("releaseImplementation", "io.flutter:armeabi_v7a_release:1.0.0-" + engineVersion);
evaluatedProject.getDependencies().add("releaseImplementation", "io.flutter:arm64_v8a_release:1.0.0-" + engineVersion);
}
if (evaluatedProject.getConfigurations().findByName("debugImplementation") != null) {
evaluatedProject.getDependencies().add("debugImplementation", "io.flutter:flutter_embedding_profile:1.0.0-" + engineVersion);
evaluatedProject.getDependencies().add("debugImplementation", "io.flutter:armeabi_v7a_profile:1.0.0-" + engineVersion);
evaluatedProject.getDependencies().add("debugImplementation", "io.flutter:arm64_v8a_profile:1.0.0-" + engineVersion);
}
evaluatedProject.getDependencies().add("compileOnly", "io.flutter:flutter_embedding_debug:1.0.0-" + engineVersion);
evaluatedProject.getDependencies().add("compileOnly", "io.flutter:armeabi_v7a_debug:1.0.0-" + engineVersion);
evaluatedProject.getDependencies().add("compileOnly", "io.flutter:arm64_v8a_debug:1.0.0-" + engineVersion);
evaluatedProject.getDependencies().add("compileOnly", "io.flutter:x86_debug:1.0.0-" + engineVersion);
evaluatedProject.getDependencies().add("compileOnly", "io.flutter:x86_64_debug:1.0.0-" + engineVersion);
});
}
}
发布到 Maven 仓库
使用 maven-publish
插件发布插件到 Maven 仓库:
gradle代码解读复制代码# 必须添加此插件 才能发布 Maven apply plugin: 'maven-publish' def localProperties = new Properties() def localPropertiesFile = rootProject.file('gradle.properties') if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) } } afterEvaluate { publishing { repositories { maven { name = 'fooRelease' allowInsecureProtocol = true url = localProperties.getProperty('mvn.url.release') credentials { username = localProperties.getProperty('mvn.username') password = localProperties.getProperty('mvn.password') } } } publications { release(MavenPublication) { groupId = localProperties.getProperty('mvn.groupid') artifactId = 'flutter-dependencies' version = "0.0.2" afterEvaluate { artifact(tasks.getByName("jar")) } } } } }
执行以下命令发布插件:
shell代码解读复制代码./gradlew publishReleasePublicationToFooReleaseRepository
在项目中使用插件
在 Flutter 插件项目的 android/build.gradle
中引入发布的插件:
gradle代码解读复制代码buildscript { repositories { # 添加你的Maven仓库地址 maven { url 'https://nexus.foo.com/repository/foo-moblie-central' content { includeGroup 'com.foo.flutter_gradle' } } google(){ content { excludeGroup 'com.foo.flutter_gradle' } } mavenCentral(){ content { excludeGroup 'com.foo.flutter_gradle' } } } dependencies { # 添加你的插件依赖 classpath 'com.foo.flutter_gradle:flutter-dependencies:0.0.1' classpath 'com.android.tools.build:gradle:7.3.0' } } # 你的插件 apply plugin: 'pharos.flutter.dependencies'
在 local.properties
文件中配置 Flutter SDK 路径:
properties代码解读复制代码sdk.dir=/Users/
/Library/Android/sdk flutter.sdk=/Users//fvm/versions/custom_3.22.0-ohos
总结
通过创建 Gradle 插件,可以有效地简化 Flutter Android 插件开发中的 Flutter 依赖配置工作,避免了每次手动配置的繁琐操作,提高了开发效率和代码可维护性。希望本文能对你有所帮助,欢迎在开发中尝试这一方法。
评论记录:
回复评论: