旧版 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 的最佳实践。

我的操作

  1. 先修改 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: 9

  • What 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

玩个毛, 不修了!

posted @ 2025-05-07 17:53  tfel-ypoc  阅读(187)  评论(0)    收藏  举报