JD Retail Cloud mPaaS における Flutter のホット リロード原理の解釈

JD Retail Cloud mPaaS における Flutter のホット リロード原理の解釈

要点:

  • JD Retail Cloud mPaaS における Flutter のホット リロードの原則を理解することは、日常の開発における効率的なトラブルシューティングに役立ちます。
  • Flutter ツールチェーンのソースコードでブレークポイントをデバッグする方法を理解します。

1. はじめに

1.1 ホットリロードとは何ですか?

ホット リロードは N 年前に使用されていたため、JS に精通している学生はそれを嘲笑するかもしれませんが、クライアント開発者にとっては、これは単純に朗報です。

まず、Flutter の公式定義を見てみましょう。

  • Flutter のホット リロード機能を使用すると、実験、UI の構築、機能の追加、バグの修正をすばやく簡単に行うことができます。ホットリロードは、更新されたソースコードファイルを実行中のシステムに挿入することで機能します。
  • Dart 仮想マシン (VM)。 VMが新しいバージョンのフィールドと関数でクラスを更新した後、Flutterフレームワークはウィジェットツリーを自動的に再構築します。
  • 変更の効果をすぐに確認できます。

簡単に言えば、変更されたソース コード ファイルを実行中の Dart 仮想マシンに挿入することで実現されます。注入後、Flutter はウィジェット ツリーを自動的に再構築します。

1.2 ホットリロードが必要なのはなぜですか?

焼畑農業の時代には、プログラマーは次のように開発とデバッグを行っていました。

プロジェクトが小さく、人数も少ない場合、図は非常に調和がとれており、効率は間違いなく高くなります。しかし現実には、大企業ではプロジェクトが大規模であることが多く、コンパイルが非常に遅く、開発者の数が多く、プロセスシステムが非常に厳格であるため、問題がないように見える開発およびデバッグプロセスが非常に苦痛になり、個人の効率が低下します。ここで強調したいのは、それが個人の効率性を指しているということです。個人的には、プロセスシステムが完璧になればなるほど、個人に対する制約が強くなると考えています。しかし、チームの観点から効率性を見ると、1+1 は 2 より大きくなければなりません。

現時点での雰囲気はこんな感じです。

[[424264]]

ホット リロードを使用すると、開発とデバッグは次のようになります。

雰囲気は次のようになります。

[[424266]]

1.3 疑問を投げかける

ホット リロードの定義については、多くの人が私と同じ疑問を抱いています。

  • どのファイルが変更されたかを知るにはどうすればいいですか?
  • 変更されたソースコードは具体的に何に変換されるのでしょうか?
  • 変更されたソース コードはどのようにして Dart 仮想マシンに挿入されるのでしょうか?
  • Flutter フレームワークはどのようにしてウィジェットの再描画をトリガーするのでしょうか?

同時に、ホット リロードを日常的に使用すると、多くの疑問に遭遇するでしょう。

  • Flutter Attach を実行した後、ホットリロードするために手動で r を入力する必要があるのはなぜですか?
  • 手動で r と入力するのは、言葉にならないデザインですが、これを自動化することはできますか?

インターネットでホットリロードに関する記事をたくさん読んだ後、次のような追加の疑問が生じます。

  • ソースコードを調べてみると、ケースが多すぎます。実際の環境をシミュレートするにはどうすればいいでしょうか?ブレークポイントで Flutter ソース コードをデバッグできますか?
  • ホット リロードはダイナミックと非常によく似ていますが、ダイナミック テクノロジーに適用できますか?

心配しないでください。この記事では上記の質問に一つずつ答えていきます。

2. ダーツのホットリロード

Flutter は開発言語として Dart を使用しているため、まずは Dart の観点からホット リロードを検証します。

2.1 検証デモを書く

dart は実行後に現在のプロセスを閉じることを考慮して、プロセスの存続を保証し、ホット リロードの効果を確認するためのタイマーを作成しました。

2.2 VMServiceを有効にする

ターミナルで dart --enable-vm-service main.dart を実行します。ここで、main.dart は 2.1 のコード ファイルです。

ターミナルに「Hello JDFlutter」という文字が連続して出力されることがわかります。

2.3 ホットリロードの実行

main.dart ファイルの印刷ログを「Hello JD」に変更し、次のようにターミナルで Observatory リンク アドレス出力を開きます。

main.dart の Isolate (読者はこれを単に dart のスレッドとして理解できますが、Isolate には共有メモリがありません)、図の赤い円を見つけて、Reload Source と入力して見つけます。

「ソースの再読み込み」をクリックすると、ターミナルは「Hello JD」という文字の出力を開始し、以下に示すようにホット リロード プロセスが完了します。

2.4 自動ホットリロード

上記の例をベースにして、ファイル監視を追加し、vm_service にメッセージを送信してホット リロードを実装します。コードは次のとおりです。

dart --enable-vm-service main.dart を直接実行し、「Hello JDFlutter」を「Hello JD」に変更します。実行結果は次のとおりです。

自動ホットリロードが正常に実装されたことがわかります。上記のコードが Dart 仮想マシンと通信する手順は次のとおりです。

  • Dart VMのWebSocketサービスURIを取得する
  • URI経由でDart VMサービスに接続する
  • サービスを通じてDart VMを取得する
  • Dart VM経由でisolateIdを取得する
  • サービスを通じてisolateIdを指定するタスクをオーバーロードする

2.5 Dart仮想マシンでできること

この時点で、自分自身を手放すことができます。 Dart サービスは、ブレークポイント、仮想マシンのステータスの取得、パフォーマンス、その他のプロトコルなど、多数の外部プロトコルを提供します。参照できるもの: Dart 仮想マシン サービス インターフェース。

3. Flutterのホットリロード

Flutter のホット リロードは、本質的には dart のホット リロードをカプセル化し、さまざまなデバイスでインストールと読み込みのプロセスを開始します。次に、Flutter ソースコードの世界に飛び込む準備をしましょう。以下の分析は、v1.22.5 ブランチのソース コードに基づいています。

諺にあるように、仕事をうまくやり遂げたいなら、まず道具を研がなければなりません。ソースコード内を長時間飛び回っていると、簡単に道に迷ってしまいます。キーメソッドを見ると、それがコードの実際のケースであるかどうかはわかりません。自分のアイデアを検証できる必要があります。最も簡単な方法は、ポイントを分解して、ターゲットを絞ってソースコードを調べることです。

3.1 IDEブレークポイント

Flutter ソースコードのダウンロードも非常に簡単です。ここでは詳細には触れません。オンラインで検索できます。 Flutter ツールチェーンのソース コードは、packages/flutter_tools にあります。

この記事では、より使い慣れた Android Studio を使用してソースコードを構成および表示します。構成は次のとおりです。

  • 最初のステップは、新しい実行構成を作成し、Dart コマンドライン アプリを選択することです。
  • 2 番目のステップは、Flutter ソース コード内のツール チェーンのエントリ ファイル (flutter_tools.dart) を見つけることです。
  • 3 番目のステップは、実行するコマンドを入力することです。
  • ステップ 4: デバッグする Flutter プロジェクトを見つけます。

設定後、ツール チェーンを使用して、指定した Flutter プロジェクトのソース コードを完全にデバッグできます。次の手順では、以下に示すように、デバイスを選択してデバッグ ボタンをクリックします。

3.2 全体的なプロセス

以下は、Flutter ホット リロードのフロー チャートです。

要するに:

  • コードの変更: ツールはプロジェクト内のファイルをスキャンし、変更時刻によって変更されたファイルを比較します。
  • 最初のコンパイル: 初めて起動すると、完全な app.dill ファイルが生成されます。
  • 増分コンパイル: 変更されたファイルをコンパイルして、app.dill.incremental.dill 増分ファイルを生成します。
  • ファイルの更新: 増分製品をデバイスにプッシュします。
  • UI 更新: DartVM は増分ファイルを受信した後にそれらをマージし、Flutter エンジンに UI を更新するように通知します。

プロセス全体でアプリを再起動する必要がないため、効率的な開発とデバッグの結果が実現します。

3.3 ソースコード解析

3.3.1 実行コマンドフロー

エントリポイントとして flutter run コマンドから分析します。このクラスは、packages/flutter_tools/lib/executable.dart の main() メソッドにあります。 run コマンドの最終的な実装クラスは、packages/flutter_tools/lib/src/commands/run.dart にあります。

RunCommand コンストラクターでは、ホット フラグがデフォルトでオンになっています。オフにする必要がある場合は、パラメータ --no-hot を追加します。

run コマンドの流れから、主なタスクはデフォルトパラメータ設定、パラメータ検証、フラッターデバイスの初期化、モード判定などであることがわかります。ホットリロードは HotRunner.run から開始されます。

3.3.2 ホットリロードプロセス - 最初の起動

HotRunner では、プロセスは複雑ではありません。

ご覧のとおり、HotRunner は次の 3 つのことを行います。

  • ターゲット デバイスの場合は、dill ファイル (カーネル ファイルと呼ばれることもありますが、基本的には中間記述であり、後で紹介されます) をコンパイルして生成します。
  • 対象デバイスにアプリをインストールして実行します。
  • アタッチを有効にするには、ターゲット デバイスを接続します。

2 番目のステップでは、さまざまなプラットフォームでさまざまなプラクティスを実行します。 iOS と Android の場合、それぞれ xcrun と adb に対応します。それはこの記事の焦点では​​ありませんし、そのプロセスは比較的長いです。詳しくは後ほどお話しします。私は最初のステップと3番目のステップに焦点を当てます。

コンパイルしてdillファイルを生成する

最後に、_compile メソッドが呼び出されます。コードが複雑すぎます。次のように直接分解してみましょう。

ブレークポイント情報から、dart ファイルがカーネル ファイル app.dill に変換されることがわかります。以下は、app.dill コンテンツの一部抜粋です。 app.dill は main.dart の内容を含む完全なコード ファイルであることがわかります。右側は main.dart ソース ファイル、左側は app.dill ファイルの内容です。

生成された app.dill は完全なコードです。次に、異なるデバイス (Android、iOS) 用のインストール パッケージをコンパイルし、指定されたパッケージを同時に実行します。

このときの app.dill を生成するプロセスを、仮に「コンパイル処理」と呼びます。増分ディルの後続のホット リロードも、このプロセスの生成を促進します。

機器を取り付ける

上記の 2 番目の手順では、デバイスがアプリの実行を開始すると、アプリ内で DartVM Observatory サービスが開きます。これは本質的に、カスタム jsonrpc2.0 プロトコルに従って通信する Websocket サービスです。アタッチすると、次に示すように URI を介してデバイス サービスに接続します。

DartVM サービスに接続すると、reloadSources、reloadMethod、hotRestart などのいくつかのホット リロード イベントが登録されます。これらのイベントはアプリ内の Dart 仮想マシンには登録されませんが、次の図に示すように、Flutter ツールの他のコマンドに提供されます。

同時に、DartVM サービスを使用して、デバイス内の Flutter 製品を初期化します。デバイス内の製品パスが一時的に生成され、XXX に置き換えられます。製品パスは次のとおりです。

  • Android の場合: file:///data/user/0/com.example.flutter_app/code_cache/XXX/flutter_app/
  • iOS シミュレーターの場合: /Users/hexianting/Resource Library/Developer/CoreSimulator/Devices/BC003085-8F19-4EF3-AB84-BD44282F79B7 (シミュレーター デバイス ID)/data/Containers/Data/Application/745DE582-59F1-4193-9692-131E611A9359/tmp/XXX/flutter_app/

具体的なコードは次のとおりです。

3.3.3 ホットリロードのトリガー

ソースコードの観点から何が行われたかを見てみましょう。

flutter run または flutter attachment を実行した後、開発者はターミナルに r と入力してリロード効果を体験できます。 Android Studio および VSCode の場合は、Ctrl+S または Cmd+S を押すだけです。

ソースコードエントリに対応:

HotReload であっても HotRestart であっても、最終的には HotRunner.restart メソッドが呼び出されます。最後まで進むと、最終的に特定のデバイス更新メソッドに到達し、上記の「ホット リロード プロセス - 最初の起動」で _compile メソッドを再度呼び出して、コンパイル プロセスに増分 dill ファイル app.dill.incremental.dill を生成するように通知します。では、この増分ファイルとは一体何なのでしょうか?デモでは、文字列「Flutter Demo Home Page」を「Flutter Demo Home Page2」に変更し、dill ファイルの内容を確認します。

最初の写真は変更前、2 番目は変更後、3 番目は増分ディル コンテンツです。増分 dill ファイルには変更された dart ファイル コードのみが含まれていることがわかります。

増分ディルが生成されると、次に示すように、_DevFSHttpWriter を介してデバイスに書き込まれます。

増分ファイルを同期した後、DartVM に UI インターフェースを更新するように通知する必要があります。この手順は上記のセクション 2.4 と似ています。

vmService.reloadSources は最終的に、次のように dart 公式ライブラリである _call メソッドを呼び出します。

HotRestart と HotReload の違い

Flutter は、HotReload と HotRestart という 2 つのクイック デバッグ方法を公式に提供しています。前者は部分的なリフレッシュが感じられず、最高のエクスペリエンスを提供しますが、欠点も明らかであり、適用範囲は比較的限られています。公式ウェブサイト HotReload に記載されている例を参照できます。以下のシナリオには適用されません。

  • enum を class に変更します。
  • フォントの変更;
  • ジェネリック型の変更。
  • Android および iOS のネイティブ変更。

HotRestart プロセスでは、HotReload プロセスと比較して、リソースのクリア操作が追加され、増分 dill ファイルが生成されなくなりました。変更ごとに完全な app.dill ファイルが生成されます。ここでは詳細は説明しません。興味のある読者はソース コードをデバッグして確認できます。

上記から、HotRestart は、非 UI アイソレートの強制終了や UI アイソレートのリセットなど、いくつかの追加処理を処理することがわかります。

デバイスに同期される dill ファイルの場所はデバイスによって異なります。

  • Android: ファイル:///data/user/0/com.example.flutter_app/code_cache/XXX/flutter_app/lib/
  • iOS シミュレーター: /Users/hexianting/Library/Developer/CoreSimulator/Devices/BC003085-8F19-4EF3-AB84-BD44282F79B7 (シミュレーター デバイス ID) /data/Containers/Data/Application/9C8E4694-AC99-4A5C-BC46-63567F1C6FD9/tmp/XXX/flutter_app/lib/

この時点で、ホット リロード ソース コードは終了です。一つ一つ紹介しきれないほどの技がたくさんあるので、ぜひ一度ご覧になってみてください。

IV.結論

上記の調査の後、この記事で提起された最初のいくつかの疑問は解決されたはずです。これは Flutter ソースコードの氷山の一角にすぎません。さらに多くのソースコードを調査する必要があります。ソースコードを読むことで、多くのことが可能になります。

  • ファイル監視 + vm_service 通信により、r または R を手動で入力する言語なしの設計が排除されます。
  • ソースコードでは複数のデバイスに制限はありません。 Flutter run は複数のシミュレーターで同時に実行され、ホット リロードを可能にします。
  • アプリを再インストールせずに、iOS シミュレーターはシミュレーター内の Flutter 製品を直接置き換えて、高速デバッグを実現します。
  • デバッグ状態の DartVM はホット リロードによって動的にすることができますが、パフォーマンスが低く、Google Flutter の高パフォーマンス目標と一致しません。

つまり、できることはたくさんあるので、ソースコードを見ることの重要性は非常に明らかです。

  • Flutter の動作メカニズムを深く理解し、Flutter フレームワークをカスタマイズします。
  • こうしたトップエンジニアの実装アイデアを研究することで、私たちは自分自身の論理体系を改善し、より厳格な人間になることができます。

V. 参考文献

  • https://flutter.dev/docs/development/tools/hot-reload
  • http://gityuan.com/2019/09/07/flutter_run/
  • https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md
  • http://static.kancloud.cn/alex_wsc/flutter_demo/1570089

<<:  5G時代が加速しています。エッジ コンピューティングが「コア」コンピューティングに取って代わるのはいつでしょうか?

>>:  ResearchAndMarkets: 世界のクラウド コンピューティング サービス業界は 2027 年に 3,131 億ドルに達する

推薦する

10年間運営しているVPS業者BuyVMのより信頼性の高い機能は何ですか?

buyvm の VPS は、(1) 自動バックアップとスナップショット、(2) ISO アップロード...

ブラックフライデー 外国ドメインホスティング VPS プロモーション概要

毎年恒例のブラックフライデーがやって来ました。Host Cat では、皆さんがあちこち探し回る必要が...

Alipayはワイヤレス決済の開発に数億ドルを投資:まず土地を占領し、それから減算を行う

アリペイはワイヤレス決済事業に数億元を投資した。彭磊最高経営責任者(CEO)と他の同社幹部は同紙に対...

tragicservers-20 USD/年/KVM/128 MB RAM/150 GB ハード ドライブ/1 TB トラフィック/ロサンゼルス

TragicServers は非常に小規模で、個人経営の企業ですが、同社の VPS は非常に評判が良...

ネットセレブのヒットの法則:老年、中年、若者の3世代

著者 | 蘇 琦編集者 | 金 宇凡「私の名前はディン・ジェンです。そしてこれは私のポニーのパールで...

evobilling - 年間 13 USD/1GB メモリ/15GB SSD/1TB トラフィック/シアトル (10GB ポート)/ロサンゼルス

EvoBurst は、実は 1 年以上前から出ています。主にローエンドの OVZ 仮想 VPS を提...

映画サイトの最適化とトラフィック導入方法についての簡単な説明

最近、映画サイトを立ち上げた友人が比較的多くいますが、実際に成功した人はどれくらいいるでしょうか?彼...

分散リンク トレースの使用方法は?

この記事はWeChatの公開アカウント「Invincible Coder」から転載したもので、著者は...

クルンはどうですか? 「Three Elite Networks」シリーズのサーバーについての簡単なレビュー

クルンはどうですか?クルンサーバーはどうですか? Kurunは国内IDC市場では比較的有名で、主に米...

Baiduの入札ランキングとネットワークマーケティングの関係について話す

Baidu の有料ランキングとは何ですか? 簡単に言えば、Baidu の有料ランキングは、Baidu...

フラッピーバードの裏に隠されたマーケティングルール

Flappy Bird は今年 2 月 10 日に開発元によって主要ストアから削除されましたが、その...

もう混乱しないでください。クラウドネイティブをこのように理解できるかもしれない

過去2年間、クラウドネイティブの人気は、2014年の3Dプリンティングや2018年のブロックチェーン...

K8S で AIOps を実装するための OpenAPI プロジェクトの紹介

背景現在、AIはあらゆる分野や業界で話題になっています。 Kubernetes ベースの DevOp...

電子商取引企業のウェブサイトの健全な発展を実現する方法

電子商取引の時代において、企業のウェブサイトの地位と役割はますます重要になってきており、ウェブサイト...

SSDVirt-512m メモリ KVM/5gSSD/G ポート/月額 5 USD

SSDVirt は、2010 年にテキサスで登録された Garrison Network Solut...