1、前语

个人于2019年5月开源了WanAndroid的Flutter版别,截止目前也有660+的star,在曩昔的4年中,咱们对Flutter的重视也越来越多,且有许多现已在商业项目中运用。

这中心也陆陆续续有不少朋友问我什么时分能晋级一下Flutter的版别,究竟太老了。所以这次也是借着这个机会,把这个项目晋级一下,熬了两个大夜,总算算是适配好了。

项目地址: https://github.com/yechaoa/wanandroid_flutter

1.1、晋级适配一览

Flutter版本从1.7.8到3.7.9的升级之旅

1.2、效果演示

Flutter版本从1.7.8到3.7.9的升级之旅

3、环境

3.1、晋级前

  • Flutter:1.7.8+hotfix.3
  • Dart:2.4.0
  • Date:2019-07-09 13:14:38
➜  wanandroid_flutter git:(master) ✗ flutter --version
  ╔════════════════════════════════════════════════════════════════════════════╗
  ║ A new version of Flutter is available!                                     ║
  ║                                                                            ║
  ║ To update to the latest version, run "flutter upgrade".                    ║
  ╚════════════════════════════════════════════════════════════════════════════╝
Flutter 1.7.8+hotfix.3 • channel stable • https://github.com/flutter/flutter.git
Framework • revision b712a172f9 (39 个月前) • 2019-07-09 13:14:38 -0700
Engine • revision 54ad777fd2
Tools • Dart 2.4.0

3.2、晋级后

  • Flutter:3.7.9
  • Dart:2.19.6
  • Date:2023-03-30 10:59:36
➜  wanandroid_flutter git:(master) ✗ flutter --version
Flutter 3.7.9 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 62bd79521d (3 天前) • 2023-03-30 10:59:36 -0700
Engine • revision ec975089ac
Tools • Dart 2.19.6 • DevTools 2.20.1

4、环境装备

因为时刻长远,中心换了电脑,终端插件也换了,之前的一些装备失效了,所以先装备环境。

第一步,环境配好之后先履行flutter doctor

4.1、无法打开“dart”,因为无法验证开发者

提示我:无法打开“dart”,因为无法验证开发者。

Flutter版本从1.7.8到3.7.9的升级之旅

因为mac系统增强了安全性的设置,所以需求在隐私与安全性里设置一下答应权限。

Flutter版本从1.7.8到3.7.9的升级之旅

4.2、无法打开“kernal-service.dart.snapshot”,因为无法验证开发者。

然后持续,又提示:无法打开“kernal-service.dart.snapshot”,因为无法验证开发者。

Flutter版本从1.7.8到3.7.9的升级之旅

依照上面刚才的操作,持续“答应”就行了。

4.3、最新版别

环境装备搞完了之后,Flutter总算算是能够用了。

履行flutter --version看看现在的版别是多少

➜  wanandroid_flutter git:(master) ✗ flutter --version
  ╔════════════════════════════════════════════════════════════════════════════╗
  ║ A new version of Flutter is available!                                     ║
  ║                                                                            ║
  ║ To update to the latest version, run "flutter upgrade".                    ║
  ╚════════════════════════════════════════════════════════════════════════════╝
Flutter 1.7.8+hotfix.3 • channel stable • https://github.com/flutter/flutter.git
Framework • revision b712a172f9 (39 个月前) • 2019-07-09 13:14:38 -0700
Engine • revision 54ad777fd2
Tools • Dart 2.4.0

顺便看看最新的版别是多少

最新正式版:docs.flutter.dev/development…

Flutter版本从1.7.8到3.7.9的升级之旅

4.4、doctor检测

Flutter环境尽管搞好了,可是项目还不能运行起来,dart文件都不能辨认

Flutter版本从1.7.8到3.7.9的升级之旅

先不管,先履行flutter upgrade试试看。

然后…不出意外的就履行挂了

Oops; flutter has exited unexpectedly.
Sending crash report to Google.
Crash report written to /Users/yechao/FlutterProjects/wanandroid_flutter/flutter_01.log;
please let us know at https://github.com/flutter/flutter/issues.

log:

## command
flutter upgrade
## exception
VersionCheckError: VersionCheckError: Command exited with code -9: git log -n 1 --pretty=format:%ad --date=iso
Standard error: 
```
#0      _runSync (package:flutter_tools/src/version.dart:522:5)
#1      FlutterVersion._latestGitCommitDate (package:flutter_tools/src/version.dart:142:12)
#2      FlutterVersion.frameworkCommitDate (package:flutter_tools/src/version.dart:133:37)
#3      FlutterVersion.toString (package:flutter_tools/src/version.dart:110:99)
#4      UpgradeCommandRunner.updatePackages (package:flutter_tools/src/commands/upgrade.dart:190:32)
<asynchronous suspension>
#5      UpgradeCommandRunner.runCommand (package:flutter_tools/src/commands/upgrade.dart:90:11)
<asynchronous suspension>
#6      UpgradeCommand.runCommand (package:flutter_tools/src/commands/upgrade.dart:47:32)
<asynchronous suspension>

看起来是dart版别的问题。然后在github的issue上看到有相同的反馈,符号已处理,可是也没看到处理方案在哪里…

然后履行flutter doctor看看

➜  wanandroid_flutter git:(master) ✗ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.7.9, on macOS 13.2 22D49 darwin-arm64, locale zh-Hans-CN)
[!] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    ✗ cmdline-tools component is missing
      Run `path/to/sdkmanager --install "cmdline-tools;latest"`
      See https://developer.android.com/studio/command-line for more details.
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.
[✗] Xcode - develop for iOS and macOS
    ✗ Xcode installation is incomplete; a full installation is necessary for iOS development.
      Download at: https://developer.apple.com/xcode/download/
      Or install Xcode via the App Store.
      Once installed, run:
        sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
        sudo xcodebuild -runFirstLaunch
    ✗ CocoaPods installed but not working.
        You appear to have CocoaPods installed but it is not working.
        This can happen if the version of Ruby that CocoaPods was installed with is different from the one being used to invoke it.
        This can usually be fixed by re-installing CocoaPods.
      To re-install see https://guides.cocoapods.org/using/getting-started.html#installation for instructions.
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.3)
[✓] IntelliJ IDEA Ultimate Edition (version 2022.2.3)
[✓] Connected device (2 available)
[✓] HTTP Host Availability
! Doctor found issues in 2 categories.

有一堆报错,先处理了再说。

4.5、cmdline-tools component is missing

说是cmdline-tools没装,那就装吧

Flutter版本从1.7.8到3.7.9的升级之旅

4.6、Android license status unknown.

然后是Android license status unknown.

履行flutter doctor --android-licenses

➜  wanandroid_flutter git:(master) ✗ flutter doctor --android-licenses
[=======================================] 100% Computing updates...             
3 of 7 SDK package licenses not accepted.
Review licenses that have not been accepted (y/N)? y
1/3: License android-googletv-license:
---------------------------------------
Terms and Conditions
// ....
10.8 Open Source Software. In the event Open Source software is included with Evaluation Software, such Open Source software is licensed pursuant to the applicable Open Source software license agreement identified in the Open Source software comments in the applicable source code file(s) and/or file header as indicated in the Evaluation Software. Additional detail may be available (where applicable) in the accompanying on-line documentation. With respect to the Open Source software, nothing in this Agreement limits any rights under, or grants rights that supersede, the terms of any applicable Open Source software license agreement.
---------------------------------------
Accept? (y/N): y
All SDK package licenses accepted

屡次同意之后就ok了。

再次履行flutter doctor

➜  wanandroid_flutter git:(master) ✗ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.7.9, on macOS 13.2 22D49 darwin-arm64, locale zh-Hans-CN)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[✗] Xcode - develop for iOS and macOS
    ✗ Xcode installation is incomplete; a full installation is necessary for iOS development.
      Download at: https://developer.apple.com/xcode/download/
      Or install Xcode via the App Store.
      Once installed, run:
        sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
        sudo xcodebuild -runFirstLaunch
    ✗ CocoaPods installed but not working.
        You appear to have CocoaPods installed but it is not working.
        This can happen if the version of Ruby that CocoaPods was installed with is different from the one being used to invoke it.
        This can usually be fixed by re-installing CocoaPods.
      To re-install see https://guides.cocoapods.org/using/getting-started.html#installation for instructions.
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.3)
[✓] IntelliJ IDEA Ultimate Edition (version 2022.2.3)
[✓] Connected device (2 available)
[✓] HTTP Host Availability
! Doctor found issues in 1 category.

4.7、装置xcode

就只剩xcode的问题了,去装一下,换电脑之后还没装过。

装置完结,再次履行flutter doctor

[✗] Xcode - develop for iOS and macOS
    ✗ Xcode installation is incomplete; a full installation is necessary for iOS development.
      Download at: https://developer.apple.com/xcode/download/
      Or install Xcode via the App Store.
      Once installed, run:
        sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
        sudo xcodebuild -runFirstLaunch
    ✗ CocoaPods installed but not working.
        You appear to have CocoaPods installed but it is not working.
        This can happen if the version of Ruby that CocoaPods was installed with is different from the one being used to invoke it.
        This can usually be fixed by re-installing CocoaPods.
      To re-install see https://guides.cocoapods.org/using/getting-started.html#installation for instructions.

然后咱们依照提示,履行一下

sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer

输入暗码,然后履行

sudo xcodebuild -runFirstLaunch

搞完又提示我这个:

[!] Xcode - develop for iOS and macOS (Xcode 14.3)
    ✗ CocoaPods installed but not working.
        You appear to have CocoaPods installed but it is not working.
        This can happen if the version of Ruby that CocoaPods was installed with is different from the one being used to invoke it.
        This can usually be fixed by re-installing CocoaPods.
      To re-install see https://guides.cocoapods.org/using/getting-started.html#installation for instructions.

CocoaPods installed but not working.然后又提到了Ruby,看起来是版别不兼容导致的。

4.8、晋级ruby

➜  ~ which ruby
/usr/bin/ruby
➜  ~ ruby -v
ruby 2.6.10p210 (2022-04-12 revision 67958) [universal.arm64e-darwin22]
➜  ~ brew install ruby
...

晋级完履行:

sudo gem install cocoapods

从头装一下cocoapods

然后不出意外的也报错了

ERROR:  Error installing cocoapods:
        The last version of activesupport (>= 5.0, < 8) to support your Ruby & RubyGems was 6.1.7.3. Try installing it with `gem install activesupport -v 6.1.7.3` and then running the current command again
        activesupport requires Ruby version >= 2.7.0. The current ruby version is 2.6.10.210.

依照提示 履行:

gem install activesupport -v 6.1.7.3

假如提示没有权限就给一下系统权限:

sudo gem update --system

然后再次履行:

sudo gem install cocoapods

5、晋级

5.1、履行flutter upgrade

装置完,再次履行flutter upgrade进行版别晋级

➜  wanandroid_flutter git:(master) ✗ flutter upgrade
Flutter is already up to date on channel stable
Flutter 3.7.9 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 62bd79521d (20 小时前) • 2023-03-30 10:59:36 -0700
Engine • revision ec975089ac
Tools • Dart 2.19.6 • DevTools 2.20.1

ok,能够晋级了。

5.2、晋级插件

然后这时分咱们还需求再把flutterdart的插件装置/晋级一下

Flutter版本从1.7.8到3.7.9的升级之旅

然后重启,这时分咱们的dart文件就能够辨认了

Flutter版本从1.7.8到3.7.9的升级之旅

可是还有一堆报错,Flutter版别从1.7.8晋级到3.7.9,跨度这么大,肯定是要适配的。

6、适配

先履行一下flutter pub get拉一下最新的依靠装备。

履行完,尽管报错少了一些,可是还有许多。

找问题最直接的办法便是,直接编译

6.1、Your Flutter application is created using an older version of the Android embedding.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Warning
──────────────────────────────────────────────────────────────────────────────
Your Flutter application is created using an older version of the Android
embedding. It is being deprecated in favor of Android embedding v2. To migrate
your project, follow the steps at:
https://github.com/flutter/flutter/wiki/Upgrading-pre-1.12-Android-projects
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
The detected reason was:
  /Users/yechao/FlutterProjects/wanandroid_flutter/android/app/src/main/AndroidManifest.xml uses `android:name="io.flutter.app.FlutterApplication"`
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Build failed due to use of deprecated Android v1 embedding.

提示有抛弃的装备,并给了晋级文档链接:github.com/flutter/flu…。

依照文档提示修正AndroidManifest文件中的android:name属性:

Previous configuration:
<application
  android:name="io.flutter.app.FlutterApplication"
  >
  <!-- code omitted -->
</application>
New configuration:
<application
  android:name="${applicationName}"
  >
  <!-- code omitted -->
</application>

6.2、No <meta-data android:name="flutterEmbedding" android:value="2"/> in xxx

再次编译

The detected reason was:
  No `<meta-data android:name="flutterEmbedding" android:value="2"/>` in /Users/yechao/FlutterProjects/wanandroid_flutter/android/app/src/main/AndroidManifest.xml

没有meta-data装备,那就加:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.yechaoa.wanandroid_flutter">
    <application >
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
    </application>
</manifest>

6.3、插件晋级

再次编译

The plugins `flutter_webview_plugin, fluttertoast` use a deprecated version of the Android embedding.
To avoid unexpected runtime failures, or future build failures, try to see if these plugins support the Android V2 embedding. Otherwise, consider removing them since a future release of Flutter will remove these deprecated APIs.
If you are plugin author, take a look at the docs for migrating the plugin to the V2 embedding: https://flutter.dev/go/android-plugin-migration.
Launching lib/main.dart on sdk gphone64 arm64 in debug mode...
Running Gradle task 'assembleDebug'...

提示这俩插件flutter_webview_plugin, fluttertoast用了过时api,需求晋级一下。

顺便把所有的插件都查看晋级一下(还好其时都留了插件地址)。

6.4、flutter_webview_plugin

遗憾的是flutter_webview_plugin现已不维护了,

The plugin `flutter_webview_plugin` uses a deprecated version of the Android embedding.
To avoid unexpected runtime failures, or future build failures, try to see
if this plugin supports the Android V2 embedding. Otherwise, consider
removing it since a future release of Flutter will remove these deprecated APIs.
If you are plugin author, take a look at the docs for migrating the plugin
to the V2 embedding: https://flutter.dev/go/android-plugin-migration.

可是在github找到了处理办法:github.com/fluttercomm…

dependencies:
	flutter_webview_plugin:
    git: https://github.com/nuc134r/flutter_webview_plugin.git

最终都晋级了这些:

Flutter版本从1.7.8到3.7.9的升级之旅

晋级完履行flutter pub get 从头拉一下。

此时项目还是不能运行的,因为文件里还是有一些报错,这时分就需求手动去改适配了。

6.5、BottomNavigationBarItem

Flutter版本从1.7.8到3.7.9的升级之旅

源码:

The argument [icon] should not be null and the argument [label]
should not be null when used in a Material Design's [BottomNavigationBar].

原来是改了字段,titlelabel

改前:

BottomNavigationBarItem(
  icon: Icon(Icons.apps),
  title: Text(YStrings.project),
),

改后:

BottomNavigationBarItem(
  icon: Icon(Icons.apps),
  label: YStrings.project,
),

6.6、Fluttertoast

Flutter版本从1.7.8到3.7.9的升级之旅

源码:

Flutter版本从1.7.8到3.7.9的升级之旅

原来是timeInSecForIos字段改成 timeInSecForIosWeb了,源码默认值便是1,能够直接去掉这个属性。

6.7、FlatButton

Flutter版本从1.7.8到3.7.9的升级之旅

找不到FlatButton,我在官网 Material Components widgets中的确没找到,暂时用TextButton代替吧,就换个名字,其他不用改。

6.8、RaisedButton

Flutter版本从1.7.8到3.7.9的升级之旅

同上,改用ElevatedButton代替吧。

6.9、Form

Flutter版本从1.7.8到3.7.9的升级之旅

源码:

  const Form({
    super.key,
    required this.child,
    this.onWillPop,
    this.onChanged,
    AutovalidateMode? autovalidateMode,
  }) : assert(child != null),
       autovalidateMode = autovalidateMode ?? AutovalidateMode.disabled;

源码现已没autovalidate这个字段了,改用AutovalidateMode

修正:

child: Form(
  autovalidateMode: AutovalidateMode.onUserInteraction,
  // ...
),

6.10、showSnackBar

Flutter版本从1.7.8到3.7.9的升级之旅

没这个api? 应该是姿态不对。

原来是Scaffold改为ScaffoldMessenger了。

修正:

ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("已移除")));

6.11、EasyRefresh

Flutter版本从1.7.8到3.7.9的升级之旅

依靠版别晋级了,flutter_easyrefresh: ^2.0.0 升到 easy_refresh: ^3.3.1,想必有许多api、运用姿态什么的都要从头适配,就得从头看下文档了。

修正后如下:

      body: EasyRefresh(
        header: PhoenixHeader(),
        footer: PhoenixFooter(),
        onRefresh: () async {
          await Future.delayed(Duration(seconds: 1), () {
            setState(() {
              _page = 0;
            });
            getHttp();
          });
        },
        onLoad: () async {
          await Future.delayed(Duration(seconds: 1), () async {
            setState(() {
              _page++;
            });
            getMoreData();
          });
        },
        child: SliverList(
          delegate: SliverChildBuilderDelegate(
            (context, index) {
              return getItem(index);
            },
            childCount: articleDatas.length,
          ),
        ),
      ),

原先自定义的PhoenixHeader现在内置就有了,直接删去自定义widget改用内置的。

slivers改为child

6.12、Dio

API文档:github.com/cfug/dio/bl…

改变记录:github.com/cfug/dio/bl…

6.12.1、connectTimeout

Flutter版本从1.7.8到3.7.9的升级之旅

改用Duration表明,比以前更规范了。

修正:

      //衔接服务器超时时刻,单位是秒.
      connectTimeout: Duration(seconds: 10),
      //呼应流上前后两次接受到数据的距离,单位为秒。
      receiveTimeout: Duration(seconds: 5),

6.12.2、InterceptorsWrapper

回调办法短少InterceptorHandler参数。

改之前:

//增加拦截器
dio.interceptors.add(InterceptorsWrapper(onRequest: (RequestOptions options) {
  print("恳求之前");
  // Do something before request is sent
  return options; //continue
}, onResponse: (Response response) {
  print("呼应之前");
  // Do something with response data
  return response; // continue
}, onError: (DioError e) {
  print("过错之前");
  // Do something with response error
  return e; //continue
}));

改之后:

//增加拦截器
dio.interceptors.add(InterceptorsWrapper(onRequest: (RequestOptions options, RequestInterceptorHandler handler) {
  print("恳求之前");
  // 假如你想完结恳求并返回一些自定义数据,你能够运用 `handler.resolve(response)`。
  // 假如你想终止恳求并触发一个过错,你能够运用 `handler.reject(error)`。
  return handler.next(options); //continue
}, onResponse: (Response response, ResponseInterceptorHandler handler) {
  print("呼应之前");
  // 假如你想终止恳求并触发一个过错,你能够运用 `handler.reject(error)`。
  return handler.next(response); // continue
}, onError: (DioError e, ErrorInterceptorHandler handler) {
  print("过错之前");
  // 假如你想完结恳求并返回一些自定义数据,你能够运用 `handler.resolve(response)`。
  return handler.next(e);
}));

6.12.3、DioErrorType

字段改变,大写变小写。

改之前:

  /*
   * error一致处理
   */
  void formatError(DioError e) {
    if (e.type == DioErrorType.CONNECT_TIMEOUT) {
      // It occurs when url is opened timeout.
      print("衔接超时");
    } else if (e.type == DioErrorType.SEND_TIMEOUT) {
      // It occurs when url is sent timeout.
      print("恳求超时");
    } else if (e.type == DioErrorType.RECEIVE_TIMEOUT) {
      //It occurs when receiving timeout
      print("呼应超时");
    } else if (e.type == DioErrorType.RESPONSE) {
      // When the server response, but with a incorrect status, such as 404, 503...
      print("出现异常");
    } else if (e.type == DioErrorType.CANCEL) {
      // When the request is cancelled, dio will throw a error with this type.
      print("恳求撤销");
    } else {
      //DEFAULT Default error type, Some other Error. In this case, you can read the DioError.error if it is not null.
      print("未知过错");
    }
  }

改之后:

  /*
   * error一致处理
   */
  void formatError(DioError e) {
    if (e.type == DioErrorType.connectionTimeout) {
      // It occurs when url is opened timeout.
      print("衔接超时");
    } else if (e.type == DioErrorType.sendTimeout) {
      // It occurs when url is sent timeout.
      print("恳求超时");
    } else if (e.type == DioErrorType.receiveTimeout) {
      //It occurs when receiving timeout
      print("呼应超时");
    } else if (e.type == DioErrorType.badResponse) {
      // When the server response, but with a incorrect status, such as 404, 503...
      print("出现异常");
    } else if (e.type == DioErrorType.cancel) {
      // When the request is cancelled, dio will throw a error with this type.
      print("恳求撤销");
    } else {
      //DEFAULT Default error type, Some other Error. In this case, you can read the DioError.error if it is not null.
      print("未知过错");
    }
  }

6.13、Gradle版别晋级

以上全部改完之后再编译

1: Task failed with an exception.
-----------
* Where:
Build file '/Users/yechao/.pub-cache/hosted/pub.flutter-io.cn/fluttertoast-8.2.1/android/build.gradle' line: 25
* What went wrong:
A problem occurred evaluating project ':fluttertoast'.
> Failed to apply plugin [id 'kotlin-android']
   > The current Gradle version 5.4.1 is not compatible with the Kotlin Gradle plugin. Please use Gradle 6.1.1 or newer, or the previous version of the Kotlin plugin.

The current Gradle version 5.4.1 is not compatible with the Kotlin Gradle plugin. Please use Gradle 6.1.1 or newer, or the previous version of the Kotlin plugin.

fluttertoast8.2.1中依靠了kotlin-android插件,需求晋级Gradle版别5.4.1到6.1.1或许更新。

这儿选择晋级Gradle版别到6.1.1,AGP用4.0.2。

晋级完Gradle再次编译,又又又报错

../../.pub-cache/hosted/pub.flutter-io.cn/provide-1.0.2/lib/provide.dart:570:28: Error: The method 'inheritFromWidgetOfExactType' isn't defined for the class 'BuildContext'.
 - 'BuildContext' is from 'package:flutter/src/widgets/framework.dart' ('../../FlutterSDK/flutter/packages/flutter/lib/src/widgets/framework.dart').
Try correcting the name to the name of an existing method, or defining a method named 'inheritFromWidgetOfExactType'.
    final widget = context.inheritFromWidgetOfExactType(_InheritedProviders);
                           ^^^^^^^^^^^^^^^^^
Target kernel_snapshot failed: Exception
FAILURE: Build failed with an exception.
* Where:
Script '/Users/yechao/FlutterSDK/flutter/packages/flutter_tools/gradle/flutter.gradle' line: 1151
* What went wrong:
Execution failed for task ':app:compileFlutterBuildDebug'.
> Process 'command '/Users/yechao/FlutterSDK/flutter/bin/flutter'' finished with non-zero exit value 1
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 14m 59s
Exception: Gradle task assembleDebug failed with exit code 1

这儿有一个provide的报错,provide用于状况办理,可是现已不维护了,所以不如直接换成provider:github.com/rrousselGit…

6.14、Provider搬迁

装备:

  runApp(MultiProvider(
    providers: [
      //将theme,favorite加到providers中
      ChangeNotifierProvider(create: (ctx) => ThemeProvide()),
      ChangeNotifierProvider(create: (ctx) => FavoriteProvide())
    ],
    child: MyApp(themeIndex),
  ));

读:

final int themeValue = context.watch<ThemeProvide>().value;

写:

context.read<ThemeProvide>().setTheme(position);

示例 ThemeProvide:

import 'package:flutter/material.dart';
class ThemeProvide with ChangeNotifier {
  int _themeIndex;
  int get value => _themeIndex;
  ThemeProvide();
  void setTheme(int index) async {
    _themeIndex = index;
    notifyListeners();
  }
}

6.15、不兼容的类型: MainActivity无法转换为FlutterEngine

搬迁完了再次编译下

/Users/yechao/FlutterProjects/wanandroid_flutter/android/app/src/main/java/com/yechaoa/wanandroid_flutter/MainActivity.java:11: 过错: 不兼容的类型: MainActivity无法转换为FlutterEngine
    GeneratedPluginRegistrant.registerWith(this);
                                           ^
注: /Users/yechao/FlutterProjects/wanandroid_flutter/android/app/src/main/java/com/yechaoa/wanandroid_flutter/MainActivity.java运用或覆盖了已过时的 API。
注: 有关详细信息, 请运用 -Xlint:deprecation 从头编译。
注: 某些音讯现已过简化; 请运用 -Xdiags:verbose 从头编译以取得完好输出
1 个过错
FAILURE: Build failed with an exception.

指向GeneratedPluginRegistrant.registerWith(this);不兼容,那就改

GeneratedPluginRegistrant.registerWith(new FlutterEngine(this));

网上找到这个方案,换成FlutterEngine(this),成果不行。

然后在官网搬迁的文档找到答案。github.com/flutter/flu…

不需求registerWith注册,条件是加了

<meta-data
    android:name="flutterEmbedding"
    android:value="2" />

并且,把原有的

import io.flutter.app.FlutterActivity;

改为

import io.flutter.embedding.android.FlutterActivity;

6.16、EasyRefresh再适配

然后再次编译。总算跑起来了,可是主页挂了

Flutter版本从1.7.8到3.7.9的升级之旅

报错:

PhoenixFooter does not support horizontal scrolling.
'package:easy_refresh/src/styles/phoenix/footer/phoenix_footer.dart':
Failed assertion: line 45 pos 12: 'state.axis == Axis.vertical'
The relevant error-causing widget was: 
  EasyRefresh EasyRefresh:file:///Users/yechao/FlutterProjects/wanandroid_flutter/lib/pages/homePage.dart:68:13
When the exception was thrown, this was the stack: 
#2      PhoenixFooter.build (package:easy_refresh/src/styles/phoenix/footer/phoenix_footer.dart:45:12)
#3      IndicatorNotifier._build (package:easy_refresh/src/notifier/indicator_notifier.dart:834:23)
#4      _EasyRefreshState._buildFooterView.<anonymous closure> (package:easy_refresh/src/easy_refresh.dart:593:34)
#5      _ValueListenableBuilderState.build (package:flutter/src/widgets/value_listenable_builder.dart:186:26)
#6      StatefulElement.build (package:flutter/src/widgets/framework.dart:5080:27)
#7      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4968:15)
#8      StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5133:11)
#9      Element.rebuild (package:flutter/src/widgets/framework.dart:4690:5)
#10     BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2743:19)
#11     WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:863:21)
#12     RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:381:5)
#13     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1289:15)
#14     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1218:9)
#15     SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1076:5)
#16     _invoke (dart:ui/hooks.dart:145:13)
#17     PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:338:5)
#18     _drawFrame (dart:ui/hooks.dart:112:31)
(elided 2 frames from class _AssertionError)

PhoenixFooter does not support horizontal scrolling.

这就没办法了,要么去掉PhoenixFooter,要么把banner放到下拉改写的上面,类似支付宝之前在页面中心的下拉改写…

改造完是这样的:

Flutter版本从1.7.8到3.7.9的升级之旅

6.17、Invalid value: Valid value range is empty: 0

还要一个Error

RangeError (index): Invalid value: Valid value range is empty: 0
When the exception was thrown, this was the stack: 
#0      List.[] (dart:core-patch/growable_array.dart:264:36)
#1      _HomePageState.getRow (package:wanandroid_flutter/pages/homePage.dart:188:57)
#2      _HomePageState.build.<anonymous closure> (package:wanandroid_flutter/pages/homePage.dart:117:24)
#3      SliverChildBuilderDelegate.build (package:flutter/src/widgets/sliver.dart:487:22)
#4      SliverMultiBoxAdaptorElement._build (package:flutter/src/widgets/sliver.dart:1422:28)
#5      SliverMultiBoxAdaptorElement.createChild.<anonymous closure> (package:flutter/src/widgets/sliver.dart:1436:55)
#6      BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2682:19)
#7      SliverMultiBoxAdaptorElement.createChild (package:flutter/src/widgets/sliver.dart:1428:12)

页面烘托的时分数据还没到,这时分按下标取值就取不到,就error了。

也比较好改,加个判断就行

  Widget getRow(int i, int length) {
    if (length==0) return null;
    return GestureDetector(
      	// ...
    );
  }

6.18、布局溢出

Flutter版本从1.7.8到3.7.9的升级之旅

咱们BaguTree的标签label太长了

这个比较好处理,加束缚constraints约束显示长度就行了

constraints: BoxConstraints(maxWidth: 150),
child: Text(articleDatas[i].superChapterName,
    style: TextStyle(color: Theme.of(context).primaryColor),
    overflow: TextOverflow.ellipsis,
    maxLines: 1)),

7、最终

以上便是Flutter从1.7.8晋级到3.7.9的全进程了,除此之外,还有查找、登录、主题适配等功能的修正及优化,就不持续展开了。

总的来说,晋级进程不算很顺利,各种编译/运行报错,疯狂翻源码,在Stack Overflow和GitHub的issue里面也是各种找处理方案,可是这个进程也能够看到Flutter的生态建设越来越老练,有越来越多的人正在拥抱Flutter。

期待Flutter未来有更好的开展~

8、GitHub

https://github.com/yechaoa/wanandroid_flutter

9、相关文档

  • Upgrading pre 1.12 Android projects
  • Flutter SDK releases
  • Dio
  • Provider
  • Flutter官网
  • pub.dev / Dart packa…
  • Material Components widgets

本文正在参与「金石方案」