六月份即将结束,咬咬牙也得把之前盛产似母猪的?给吹完~
继续来吧~ 干完这篇,估计看看状态吧,得休息休息了_
因为Flutter2.0已经出来很久了,空安全(Null-Safety)也说了好一阵了。但是就Flutter这个鬼德性,不敢动呀!虽然已上线的项目Flutter SDK已经跑在Flutter 2.0之上了,有问题的第三方库也已经更新了。但是它重点宣传的Null-safety没敢动。
试了试“dart migrate --skip-import-check”命令来自动将项目迁移到空安全上,命令运行完,打开生成的链接,一万个草泥马飘过,几百个Change。哥惹不起,默默x掉了窗口。看着窗外,冷静了几分钟。不禁笑出了声,还好哥机智~
预知详情,请看下图:

这是一次失败的尝试,让我耿耿于怀。以偶这个暴脾气,非得给你整个底掉儿~
命运就是这样,机会如期而至。需要弄个新App,功能差不多定制版。全套代码就复制过来了。这不得跟你空安全掰掰手腕,完全没有线上p0的恐惧感~
这种搞法就是既然Flutter升级了,那我需要使用2.0的SDK。但是呢,我又怕p0事故不想整空安全,那怎么办?
其实我们直接升级Flutter2.0,跑一跑工程修改升级几个有问题的第三方库就可以了。
只要你的dart版本最低不大于:>=2.12.0就好了
environment:
sdk: ">=2.10.0 <3.0.0"
升级Fultter 2.0SDK可以去官网下载Sdk,也可以直接通过命令升级
//升级Flutter
flutter upgrade
//查看flutter version
flutter --version
//查看插件依赖树
flutter pub deps
但是,这毕竟是个假2.0,就这样一笔带过吧~
首先,我当然不是一马当先,上来就升级,搞搞搞,搞炸它~
毕竟我也是摸着官文过活,附上官方文档:https://dart.dev/null-safety/migration-guide
首先检查当前Flutter版本
flutter –version
如果在flutter 2.0以下,将flutter升级到2.0。使用命令flutter upgrade在原有1.0上升级或者去官网下载flutter 2.0 SDK解压配置环境等。
Flutter升级到2.0以后,flutter并没有强制你的应用就必须马上使用空安全,这样的话我们不需要修改在pubspec.yaml中的sdk设置在2.12.0以上
//❌错误配置
environment:
sdk: '>=2.12.0 <3.0.0'
//✅正确配置
environment:
sdk: '>=2.10.0 <3.0.0'
如果设置>=2.12.0,那么Dart分析器将会去检查空安全,那么恭喜你会看到一片红海。
官方是的升级说明呢:因为第三方库肯定是有依赖关系的,如图2.2:

官网的建议是:我们强烈建议按顺序迁移代码,首先迁移依赖图的叶子。例如,如果包 C 依赖于包 B,而包 B 又依赖于包 A,那么 A 应该先迁移到空安全,然后是 B,然后是 C。
但是这样的话,貌似很不好操作,有时候第三方库虽然依赖某个库,但是我们项目又没有,不可能我一个个又给它加到pubspec.yaml文件中,这不现实。
莫急~ 我们就不按官方来了,开始我们的骚操作吧。
使用以下命令获取包依赖项的迁移状态,它将告诉你哪些库是支持空安全的,如下图2.3.1:
dart pub outdated --mode=null-safety

上图Current列代表你项目的当前版本,Latest代表最新的版本,绿色代表这个依赖库已经支持空安全了,比个二✌️,红色的就GG了,不支持空安全。当然现在在pub.dev上的库基本上都支持空安全了。还有不支持的,那你也可以放弃使用了,因为它估计基本不维护了?。
因为我们用“dart pub upgrade --mode=null-safety”,检测第三方库支持空安全的情况。发现很多库暂时还没支持,怎么办呢?那我们可不可以先升级支持空安全的库呢?那当然是没问题的。看到下图2.3.1:

实际上,它也告诉我们通过“dart pub update --null-safety --dry-run”命令去输出原因并升级。
咱试一试~~
如图2.3.2:

它解释了有哪几个库不支持空安全,然后告诉我们可以用以下命令升级支持空安全的第三方库:
dart pub upgrade --nullsafety flustars uuid fluro photo_manager json_annotation video_player webview_flutter json_serializable dio photo_view video_thumbnail path_provider device_info shared_preferences cached_network_image flutter_rating_bar extended_text cupertino_icons build_runner graphql_flutter firebase_database rxdart flutter_keyboard_visibility connectivity flutter_screenutil flutter_svg url_launcher amplitude_flutter intl firebase_core smartlook event_bus firebase_auth permission_handler app_review test back_button_interceptor
OKOK 咱耐着性子继续来试一试!
运行以上的命令结果告诉我,依赖冲突:
Because client depends on euma_calendar_v1 0.0.23 which depends on intl ^0.16.1, intl ^0.16.1 is required.
So, because client depends on intl >=0.17.0-nullsafety.2, version solving failed.
因为不同库依赖的intl版本不一致导致了冲突,那么我们得解决它才能继续往下走,如何解决?很简单
在pubspec.yaml文件中dependency_overrides下添加支持空安全的intl版本,给它强指定!
environment:
sdk: ">=2.12.0 <3.0.0"
dependency_overrides:
intl: 0.17.0
...
dependencies:
flutter:
sdk: flutter
flustars: ^2.0.1
...
这里我们使用dependency_overrides来强行指定依赖库版本。以为这样世界就该安静了,可还是太年轻,接着运行上面的upgrade命令,又给我报了另一个依赖错误:
Because every version of euma_calendar_v1 depends on flustars ^0.3.3 and client depends on flustars >=2.0.0, euma_calendar_v1 is forbidden.
So, because client depends on euma_calendar_v1 0.0.23, version solving failed.
说flustars这个库冲突了,欧拉,我们再依葫芦画瓢吧,
dependency_overrides:
intl: 0.17.0
flustars: 2.0.1
在我依葫芦画瓢N个之后,终于支持空安全的第三方库全部升级好了,大家不要被N吓到了,夸张手法
dependency_overrides:
# intl: 0.17.0
# flustars: 2.0.1
# path_provider: 2.0.2
# crypto: 3.0.1
# convert: 3.0.0
# json_serializable: 4.1.3
# json_annotation: 4.0.1
# dio: 4.0.0
# timezone: 0.7.0
# sqflite: 2.0.0+3
# file: 6.1.1
# flutter_cache_manager: 3.1.0
# archive: 3.1.2
这里这些强指定的库都注释掉了,因为这里其实是一个临时存储类似的概念,先强指定,为了升级第三方库。等所有的第三库都升级成功了之后,这里就可以慢慢干掉了。我都干完了~
之后你还可以用“dart pub outdated --mode=null-safety”来检测一下是否所有库都已经升级到空安全版本,如果有一些pub.dex库没有支持空安全,那么我们就寻找替代的库。如果是自己的私有第三方库,那就自己先升级第三方库支持空安全,和本篇文章是大同小异的。
全部升级好了会提示如图2.3.3:

前期准备工作包括Dart升级,第三方库升级我们都做好了,接下来就来到了最重要的环节,使用以下命令迁移项目代码到空安全:
//优先使用
dart migrate
//上面命令报错了的话,使用
//说明你还有插件没有完全支持空安全声明,使用以下命令迁移
dart migrate --skip-import-check
运行命令后,会提供给你一个连接,点击连接进入一个迁移前后对比的网页,如图2.4.1:

应该会有惊喜又名惊吓,几百条改动。你可以在这里查看和修改,也可以直接APPLY MIGRATION接受迁移改动,这样的话,迁移的代码改动就到工程了。
你以为这样就皆大欢喜了吗?放心好了,Flutter从不讲武德,还是会有很多爆红的,这你就得一处处去修改了。这里列几个常见的问题吧
List list = List(); => List list = [];
Before:
R runZoned<R>(R body(),
{Map<Object?, Object?>? zoneValues,
ZoneSpecification? zoneSpecification,
@Deprecated("Use runZonedGuarded instead") Function? onError})
After:
R? runZonedGuarded<R>(R body(), void onError(Object error, StackTrace stack),
{Map<Object?, Object?>? zoneValues, ZoneSpecification? zoneSpecification})
Stack 控件的 overflow 参数也被 Deprecated ,需要替换为 clipBehavior,比如以前的 Overflow.visible 可以修改为 Clip.none ,默认情况下是 Clip.hardEdge

FlatButton 也被标志为弃用,需要替换成 TextButton;(padding、color等参数需要使用ButtonStyle来设置)


Dio的新版本InterceptorsWrapper和以前的不一样了需要做相应的改动
大概主要就这些了,其他的还有一些零零碎碎其实占主力军的,是一些加?或者其他判断可空非空逻辑,这得看具体逻辑做相应修改了,因为dart tool在做迁移的时候可能比较笨,没有很友好的转化,但是编译器检测出来了。就给爆红了。这块基本是体力活和干死脑细胞运动。慢慢来吧~ 等爆红全部消除的时候,来到下一节。
(这里注意的是:有可能编译期静态检测空安全并没有啥问题了,但是运行期有报错说null啥啥啥的问题,基本是空安全的问题,说明有得地方还是没覆盖到,在去逐个改吧,碰上了就改下)
看似经历了上面几个步骤,感觉没啥问题了,可以跑一跑了吧。
其实用"dart analyze"和"dart test" , dart的分析和测试命令来检测是否项目真正适配了空安全,这里略过,大家可以试试,一般是Warning,大家看着改吧,不影响运行。
到这,大家可以在Android Studio或者命令行运行项目看一看耗死我们无数个脑细胞的玩意到底能不能跑了。
如果跑起来了呢,那么恭喜恭喜~ 没跑起来多半是有一些依赖库,或者是自己私有库还没完全支持空安全。也不用急着马上升级才能跑。Dart还是留了后手,有一种混合模式可以跑起来
dart –no-sound-null-safety run
flutter run –no-sound-null-safety

那么这种的话就有个弊端,因为有时候Android Studio对编译跑iOS不是很友好,有时候跑不起了,跑得又慢就可以用xcode。那样快很多,这时候的话就没办法用Xcode跑了。所以,还是最好全迁空安全。
使用“–no-sound-null-safety”,我验证了能用命令行打包和运行。
因为我自己本身也是前边有私有库,没有吧库全部迁移到空安全版本,也就是说有几个库暂时不支持空安全,所有我就加了这个参数跑。后来也吧私有库升级了,就可以去掉这个参数了。
PS: 这里提一个全迁后Android打包遇到的问题,其实不是全迁的问题。后来查到是因为龟儿子将gradle从gradle-5.6.2-all升级了gradle-6.5-bin的问题,后来两种gradle版本都解决了。
类似于
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:lintVitalRelease'.
> Could not resolve all artifacts for configuration ':app:debugRuntimeClasspath'.
> Failed to transform libs.jar to match attributes {artifactType=processed-jar, org.gradle.libraryelements=jar, org.gradle.usage=java-runtime}.
> Execution failed for JetifyTransform: /Users/michaelbui/Projects/counter/build/app/intermediates/flutter/debug/libs.jar.
> Failed to transform '/Users/michaelbui/Projects/counter/build/app/intermediates/flutter/debug/libs.jar' using Jetifier. Reason: FileNotFoundException, message: /Users/michaelbui/Projects/counter/build/app/intermediates/flutter/debug/libs.jar (No such file or directory). (Run with --stacktrace for more details.)
Please file a bug at http://issuetracker.google.com/issues/new?component=460323.
* 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
第一种:不做修改将gradle版本降回gradle-5.6.2-all
第二种:在app/build.gradle中加入以下代码可解决:github issue链接:https://github.com/flutter/flutter/issues/58247
android{
lintOptions {
checkReleaseBuilds false
}
}
Flutter2.0 空安全迁移是迁移完了,后面可以妥妥的升级SDK了。但是运行后报奇奇怪怪问题就再说了,遇到了就解决掉O(∩_∩)O哈哈
申明:禁用于商业用途,如若转载,请附带原文链接。https://www.jianshu.com/p/e2a5fedb4e22蟹蟹~
PS: 写文不易,觉得没有浪费你时间,请给个关注和点赞~ ?
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A
我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘
我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="
假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit
在Ruby中是否有Gem或安全删除文件的方法?我想避免系统上可能不存在的外部程序。“安全删除”指的是覆盖文件内容。 最佳答案 如果您使用的是*nix,一个很好的方法是使用exec/open3/open4调用shred:`shred-fxuz#{filename}`http://www.gnu.org/s/coreutils/manual/html_node/shred-invocation.html检查这个类似的帖子:Writingafileshredderinpythonorruby?
Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u
我正在使用ruby2.1.0我有一个json文件。例如:test.json{"item":[{"apple":1},{"banana":2}]}用YAML.load加载这个文件安全吗?YAML.load(File.read('test.json'))我正在尝试加载一个json或yaml格式的文件。 最佳答案 YAML可以加载JSONYAML.load('{"something":"test","other":4}')=>{"something"=>"test","other"=>4}JSON将无法加载YAML。JSON.load("
我正在尝试创建一个带有项目符号字符的Ruby1.9.3字符串。str="•"+"helloworld"但是,当我输入它时,我收到有关非ASCII字符的语法错误。我该怎么做? 最佳答案 你可以把Unicode字符放在那里。str="\u2022"+"helloworld" 关于ruby-如何在Ruby字符串中插入项目符号字符?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1195
我的Rails站点使用了一个确实不是很好的gem。每次我需要做一些新的事情时,我最终不得不花费与向实际Rails项目添加代码一样多的时间来为gem添加功能。但我不介意,我将我的Gemfile设置为指向我的gem的GitHub分支(我尝试提交PR,但维护者似乎已经下台)。问题是我真的没有找到一种合理的方法来测试我添加到gem的新东西。在railsc中测试它会特别好,但我能想到的唯一方法是a)更改~/.rvm/gems/.../foo。rb,这看起来不对或者b)升级版本,推送到Github,然后运行bundleup,这除了耗时之外显然是一场灾难,因为我不确定我所做的promise是否正