Flutter: Navigatorで、Do not use BuildContexts across async gaps の警告が出る

結論:「if (!mounted) return;」の1文を追加する

2022/7/24 Flutter エラー・バグ日記

 

画面遷移をさせるため、ごく一般的な「Navigator.pushReplacement(context, ・・・」のような記述をしたところ、警告の波線が出るようになった。

 

カーソルを当てて内容を見ると、「Do not use BuildContexts across async gaps.」という警告コメントが表示される。

 

本記事はライトな日記思考で書いているので、詳細説明はしておらず、基本、テキストのみで画像とかは載せておりません。。m(_ _)m

解説記事ではないため、解決していない内容や、その時々の間違った解釈を述べてしまっている可能性が大いにありますので、何卒、ご了承ください。

 

警告コメントの脇にある「Documentation」のリンクをたどると、以下の説明ページに飛んだ。

 

 

内容を読んだ自分なりの理解としては、非同期処理中に、「Navigator」のように、contextを渡す処理があると、非同期処理から戻ってきたときに、既に画面遷移が終わっていて、元の画面のcontextが無くなっているのでエラーになる、という状況を防ぎましょう、ということらしい。

 

上記「Documentation」にある対策は、「Navigator」の前に、「if (!mounted) return;」をつけるというもの。

 

確かに下記のように1文を追記すると、警告コメントは表示されなくなった。

 

class _MyWidgetState extends State<MyWidget> {
  ...

  // 非同期処理(async, await)の中でcontextを渡している
  void onButtonTapped() async {
    await Future.delayed(const Duration(seconds: 1));

    // contextを渡す前に、contextが現在のWidgetツリー内に存在しているかどうかチェック
    // 存在しなければ、画面遷移済を意味するので、以降の画面遷移処理は行わない
    if (!mounted) return;

    Navigator.of(context).pop();
  }
}

 

要は、contextが無くなっていたら、早期リターンしてNavigatorを実行させないようにする、ということだと思われる。

 

※「mounted」プロパティについては以下に説明がある。Stateful Widgetのオブジェクトが、現在のWidgetツリー内に存在するか否かを示すbool型のプロパティのこと(存在しなければ、既に別のWidgetツリーに移っている=画面遷移している、ということだろう)。

 

 

確かに過去に作成していたアプリで、画面遷移をした後に、

 

This widget has been unmounted, so the State no longer has a context

 

というエラーが出たことがよくあった。

 

このとき、ググって対策を調べたら、「if (mounted) { }」で処理をラップすると良い、という情報があり、これでエラーを回避していた。

 

 

恐らく今回の警告は、この危険性を事前に察知してくれるものなのだろう。

 

「Documentation」によると、この警告は「Linter v1.1」となっている。

 

Flutter3にアップグレードして新規プロジェクトを作成すると、「pubspec.yaml」には「flutter_lints: ^2.0.0」がインポートされているので、恐らくアップグレードしたことでこの警告が機能するようになったのだと思われる(アップグレード前は「flutter_lints: ^1.0.0」だった)。

 

警告が出ると厄介に感じがちだが、こうして先回りしてエラーを防いでくれるのは、非常にありがたい。

 

\一般的なエラー対処法をまとめた記事はこちら/

 

リリースしたアプリ(全てFlutterで開発)

OCR文字認識Fast -シンプルな高精度・日本語スキャナー

Google Play で手に入れよう
Download on the App Store

 

暗記用マーカー - シンプル穴埋め問題作成

Google Play で手に入れよう
Download on the App Store

 

超即ToDo –最短2タップで通知登録できるタスク管理アプリ

Google Play で手に入れよう
Download on the App Store

 

かんたんプリント管理:アラート・OCR文字認識・検索機能を搭載

Google Play で手に入れよう
Download on the App Store

 

シンプルメモ帳「BasicMemo」 - 文字カウント、ワンタッチ入力、タグ管理等の機能を搭載

Macのデスクトップ版もリリースしました。

Google Play で手に入れよう
Download on the App Store

 

個人アプリ開発で役立ったもの

おすすめの学習教材

超初心者向けでオススメな元Udemyの講座/

 

 \キャンペーン時を狙えば安価で本場の内容が学べる/

 

\Gitの基礎について無料で学べる/

 

おすすめの学習書籍

実用的image_pickerに関してかなり助けられた/

 

Dartの基礎文法を素早くインプットできる/


Dart入門 - Dartの要点をつかむためのクイックツアー

 

おすすめのソフトウェア

安くて高機能。アプリの独自ドメイン・紹介サイト構築に最適/

 

\アイコン作成・画面設計・クラウド保存...何でもできて超必須

Microsoft Public Affiliate Program (JP)(マイクロソフトアフィリエイトプログラム)

 

おすすめのハードウェア

\リーズナブルな価格で検証端末を確保できる/

 

\目線の高さを調節しやすく、疲れにくい

 

\キータッチが超静音で心地よい/

 

おすすめのサポートアイテム

\部屋の中を仕切って、集中できる開発環境を作れる/

 

\部屋の中でも大き過ぎず、長時間座っても疲れない

 

\バグと格闘した後の肩こりを解消してくれる/

タイトルとURLをコピーしました