はっきり言って面倒臭い
プログラミングの際にオブジェクトを代入する変数をnull
で初期化して、その変数がnull
かどうかで条件分岐する、なんてコードをよく書いていたので、また面倒なことが増えたって気がしますが、実行時のNull Pointer Exceptionを避ける意味はあるのでしょう。はっきり言ってこういう仕組みは普段テストを書く習慣が無い人のためにあるんじゃないの?って気もしますが、世の流れには逆らえずFlutter製のアプリ(マンカラナッツ)でも対応することにしました。
パッケージの依存状況を調べる
flutter pub outdated --mode=null-safety
と打てば、使用しているパッケージがNull Safety対応済みかどうか分かります。
$ flutter pub outdated --mode=null-safety
Showing dependencies that are currently not opted in to null-safety.
[✗] indicates versions without null safety support.
[✓] indicates versions opting in to null safety.
Package Name Current Upgradable Resolvable Latest
direct dependencies:
flutter_google_ad_manager ✗0.11.1 ✗0.11.1 ✗0.11.1 ✗0.11.1
dev_dependencies: all support null safety.
You are already using the newest resolvable versions listed in the 'Resolvable' column.
Newer versions, listed in 'Latest', may not be mutually compatible.
以前にも少し作業したので、マンカラナッツの場合はNull Safetyに対応していないのはflutter_google_ad_manager
だけです。というかこのパッケージ(flutter_google_ad_manager
)が対応されるのを待っていた状態でした。対応作業する前は自分で作ったパッケージ(karah_think.so)もこのリストに表示されていたのですが、既に修正したので、今回はflutter_google_ad_manager
の代わりにadmob_flutter
を使うことで対応しました。作業内容は使用例に書かれているので簡単でした。
コードの修正
以前にNull Safety対応作業した時には既にFlutter2.0だったのですが、今回Flutter upgrade
してから作業するといくつか追加の作業が必要でした。以前flutter_google_ad_manager
部分をコメントにしてビルドした時には既にSound Null Safety
と表示されていたのですが、Flutter自体が完全にNull Safetyになっていなかったのでしょうか?今回AndroidStudioのバージョンアップ(4.2.2
)もしたので、それも関係あるのかも知れませんがよく分かりません。
今回の環境は以下の通りです。
$ flutter --version
Flutter 2.2.3 • channel stable • https://github.com/flutter/flutter
Framework • revision f4abaa0735 (8 days ago) • 2021-07-01 12:46:11 -0700
Engine • revision 241c87ad80
Tools • Dart 2.13.4
修正例
修正前
GlobalKey _keyBoard = GlobalKey();
RenderBox _box;
if (_box == null)
WidgetsBinding.instance.addPostFrameCallback((_afterLayout){
setState(() {
_box = _keyBoard.currentContext.findRenderObject();
});
});
修正後
final GlobalKey _keyBoard = GlobalKey();
late RenderBox _box;
WidgetsBinding.instance!.addPostFrameCallback((_) {
setState(() {
_box = _keyBoard.currentContext!.findRenderObject() as RenderBox;
});
});
遅延初期化のためのlate
キーワードが使えるようになったのはDart2.12からだそうです。また、as
を使って明確に型を指定しないとビルド出来なくなっていました。C++のように型にうるさくなっていくのでしょう。
修正後
$ flutter pub outdated --mode=null-safety
Showing dependencies that are currently not opted in to null-safety.
[✗] indicates versions without null safety support.
[✓] indicates versions opting in to null safety.
All your dependencies declare support for null-safety.
AdMob用のパッケージをadmob_flutter
に変えたことで、Null Safety非対応のプラグインはなくなりました。
$ flutter build apk --release
💪 Building with sound null safety 💪
Picked up _JAVA_OPTIONS: -Djava.net.preferIPv6Addresses=true
Running Gradle task 'assembleRelease'...
Running Gradle task 'assembleRelease'... Done 121.0s
✓ Built build/app/outputs/flutter-apk/app-release.apk (60.1MB).
ビルド時に絵文字が出て、Sound Null Safety
と表示されます。
目出度くマンカラナッツはVersion1.2.2からNull Safety
になりました。