旧版 Flutter 开发的项目如何在新的版本上运行起来?
Cursor “最佳” 实践
好的,我来总结一下我们对旧项目做的主要修改:
1. **Gradle 配置更新**:
- 更新了 `gradle-wrapper.properties` 中的 Gradle 版本到 8.10.2
- 在根目录 `build.gradle` 中:
- 添加了 Kotlin 支持(版本 1.9.22)
- 更新了 Android Gradle 插件版本到 8.1.0
- 将 jcenter() 替换为 mavenCentral()
2. **Android 项目结构更新**:
- 将 Java 版本的 `MainActivity` 转换为 Kotlin 版本
- 创建了新的 `MainApplication` 类来支持 Flutter Engine V2
- 更新了 `AndroidManifest.xml`:
- 添加了 Flutter V2 embedding 支持
- 更新了主题配置
- 添加了必要的 meta-data 标签
3. **Gradle 构建系统更新**:
- 在 `settings.gradle` 中:
- 添加了 pluginManagement 块
- 添加了 dependencyResolutionManagement 块
- 更新了 Flutter 插件加载方式
- 在 `app/build.gradle` 中:
- 使用新的 plugins 块语法
- 更新了编译和目标 SDK 版本
- 添加了 Kotlin 支持
- 添加了必要的编译选项
4. **依赖更新**:
- 在 `pubspec.yaml` 中:
- 更新了 SDK 版本范围到 ">=2.12.0 <4.0.0"
- 更新了 cupertino_icons 到 ^1.0.8
5. **项目结构优化**:
- 创建了 Kotlin 源代码目录
- 删除了旧的 Java 源代码
- 更新了资源文件结构
这些修改主要是为了:
1. 支持最新的 Flutter 和 Android 开发环境
2. 迁移到 Flutter V2 embedding
3. 支持 Kotlin
4. 使用最新的 Gradle 构建系统
5. 确保项目能在现代 Android 设备上正常运行
最终,我们通过创建新项目并迁移代码的方式,确保了所有配置都是最新的,并且符合 Flutter 的最佳实践。
我的操作
- 先修改 pubspec.yaml
name: balabala
description: A new Flutter application.
version: 1.0.0+1
environment:
## 这里 sdk 版本需要修改
sdk: ">=2.12.0 <4.0.0"
dependencies:
flutter:
sdk: flutter
## 这里依赖版本可能要改
cupertino_icons: ^1.0.8
# Use Audioplayers dependency version 0.17.4
dev_dependencies:
flutter_test:
sdk: flutter
flutter:
uses-material-design: true
assets:
- assets/
报错
FAILURE: Build failed with an exception.
- What went wrong:
Could not open settings generic class cache for settings file '/.../android/settings.gradle' (/.../.gradle/caches/7.0.2/scripts/1445wdyck9xmnqxfk9atcnkpf).
BUG! exception in phase 'semantic analysis' in source unit 'BuildScript' Unsupported class file major version 65
处理方法
切换 Java version
# 先检查一下本机已有的 Java 版本
/usr/libexec/java_home -V
# 切换到 Java 17
export JAVA_HOME=/usr/local/Cellar/openjdk@17/17.0.15/libexec/openjdk.jdk/Contents/Home
# 清理后再次尝试编译
## 项目根目录
flutter clean
cd android
./gradlew clean
cd ..
flutter pub get
gradlew clean 报错
FAILURE: Build failed with an exception.
- What went wrong:
Could not open settings generic class cache for settings file '/.../android/settings.gradle' (/.../.gradle/caches/7.0.2/scripts/1445wdyck9xmnqxfk9atcnkpf).
BUG! exception in phase 'semantic analysis' in source unit 'BuildScript' Unsupported class file major version 65
处理
修改 android/gradle/wrapper/gradle-wrapper.properties
#distributionUrl 7.0.2 -> 7.5
修改 android/build.gradle
buildscript {
dependencies {
// 7.0.1 -> 7.3.0
classpath 'com.android.tools.build.gradle:7.3.0'
}
}
再清理执行
rm -rf ~/.gradle/caches/ && cd .. && flutter clean && flutter pub get
flutter run 继续报错
FAILURE: Build failed with an exception.
- What went wrong:
Could not open settings generic class cache for settings file '/.../android/settings.gradle' (/.../.gradle/caches/7.5/scripts/czaqb3f6m3cizpr0e13jhsz19).
BUG! exception in phase 'semantic analysis' in source unit 'BuildScript' Unsupported class file major version 65
处理
rm -rf ~/.gradle/caches/ ~/.gradle/wrapper/ && rm -rf android/.gradle
修改 android/build.gradle
buildscript {
repositories {
google()
// 移除 jcenter()
mavenCentral()
}
allprojects {
google()
// 同样移除 jcenter()
mavenCentral()
}
}
再次 执行
flutter clean && flutter pub get && cd android && ./gradlew clean && cd .. && flutter run
报错
FAILURE: Build failed with an exception.
- Where:
Script '/.../flutter/packages/flutter_tools/gradle/flutter.gradle' line: 9
处理
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new FileNotFoundException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
// 旧的是
//apply plugin: 'com.android.application'
//apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
plugins {
id 'com.android.application'
id 'dev.flutter.flutter-gradle-plugin'
}
android {
namespace "co.appbrewery.xylophone"
//修改 29 -> 33
compileSdkVersion 33
lintOptions {
disable 'InvalidPackage'
}
defaultConfig {
applicationId "co.appbrewery.xylophone"
minSdkVersion 23
//修改 29 -> 33
targetSdkVersion 33
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
buildTypes {
release {
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
dependencies {
//这行貌似也是新增
implementation 'androidx.core:core-ktx:1.9.0'
}
修改 android/settings.gradle
/*旧
include ':app'
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
}
*/
pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
def propertiesFile = new File(rootProject.projectDir.parentFile, 'local.properties')
if (propertiesFile.exists()) {
propertiesFile.withReader('UTF-8') { reader -> properties.load(reader) }
}
def flutterSdk = properties.getProperty('flutter.sdk')
assert flutterSdk != null, "flutter.sdk not set in local.properties"
return flutterSdk
}()
includeBuild("${flutterSdkPath}/packages/flutter_tools/gradle")
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
include ':app'
rootProject.name = 'android'
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
}
继续报错
Where:
Settings file '/.../android/settings.gradle' line: 9What went wrong:
A problem occurred evaluating settings 'android'.
> flutter.sdk not set in local.properties. Expression: (flutterSdk != null).
处理
# 项目根目录
flutter doctor -v | grep "Flutter SDK" | awk '{print $3}' > android/local.properties && echo "flutter.sdk=$(cat android/local.properties)" > android/local.properties

浙公网安备 33010602011771号