はじめに
Flutter Daemon
という機能 (ツール) がありましたので、紹介したいと思います。
Flutter Daemonとは?
Flutter は通常 Flutter SDK で提供されるコマンド群でビルドや各デバイスへのインストールなどが行われます。
一番よく使うのはアプリ実行のために利用する$ flutter run
コマンドですね。この flutter コマンドからターゲットデバイスの Android や iOS などに対して、adb や Xcodeのプロトコルで繋がった通信経路の中で Flutter Engine と Host PC の Flutter SDK との間でやり取りを行っています (ここのプロトコルも後々調べたい) 。
Flutter SDK は外部から操作可能なツール (I/F) をFlutter Daemon
としてユーザ (開発者) に提供しています。Flutter Daemon
を利用すると、ユーザの操作でホットリロードやアプリの終了、開始、インストール等が行えます。複数デバイスを同時に操作するときには便利そうです。
VSCodeのFlutterプラグインはこの機能を利用している?
ソースコード
ソースコードはpackages/flutter_tools/lib/src/commands/daemon.dartです。
プロトコル
提供される入出力はstdin/stdout
のみで、フォーマットはJSON-RPC
です。httpとかは無さそうなので、必要なら自分でブリッジを作る必要がありそうです。
使い方
Flutter Daemon
を立ち上げるには以下のコマンドを実行します。
$ flutter daemon
Starting device daemon...
[{"event":"daemon.connected","params":{"version":"0.5.3","pid":4365}}]
操作方法は、JSON-RPCをターミナルに直接入力するか、Linux環境であればstdin ( /proc/${pid}/fd/0 )
に入力でも出来ます。
まずはdaemon.version
でFlutter Daemonのバージョン情報を取得してみます。
id
はクライアント側が自由に決められる番号です。サーバー側はクラアントへそのid
を添えてリプライを返してきます。
$ [{"method":"daemon.version","id":2}]
[{"id":2,"result":"0.5.3"}]
アプリの実行や各種操作するにはappId
が必要なので、認識しているデバイスを取得してみると
$ [{"method":"device.getDevices","id":2}]
[{"id":2,"result":[]}]
????
何も返してくれません。appId
が必要なのですが…。
仕方がないので適当なappId
で試してみます。
$ [{"event":"app.start","params":{"appId":"53ee146d-ca2a-4886-ad3a-1291cb52e25c","deviceId":"macOS","directory":"/Users/kurun/workspace/flutter-app","supportsRestart":true,"launchMode":"run"},"id":2}]
[{"id":2,"error":"unexpected response with id: 2","trace":"#0 Daemon._handleRequest (package:flutter_tools/src/commands/daemon.dart:168:11)\n#1 _rootRunUnary
〜 略
うまくいきません。
諦めます。
その他の使い方はFlutter Daemon
を参照してください。
他の方法
アプリ実行後にそのままデーモンを立ち上げ続ける方法があるので、こちらを利用します。
% flutter run --machine
この状態からソースコードを変更して、ホットリロードするには以下のようにapp.restart
を実行します。
appId
は上記コマンド実行時のログに表示されているappId
を指定します。
[{"method":"app.restart", "id":2, "params":{"appId":"189f0050-4f0a-4357-b0d8-72653cdbe698", "fullRestart":true}}]
ホットリロード出来ました!
参考↓
[{"event":"app.progress","params":{"appId":"189f0050-4f0a-4357-b0d8-72653cdbe698","id":"2","progressId":"hot.restart","message":"Performing hot restart..."}}]
[{"event":"app.progress","params":{"appId":"189f0050-4f0a-4357-b0d8-72653cdbe698","id":"3","progressId":null,"message":"Syncing files to device macOS..."}}]
[{"event":"app.progress","params":{"appId":"189f0050-4f0a-4357-b0d8-72653cdbe698","id":"3","progressId":null,"finished":true}}]
[{"event":"app.progress","params":{"appId":"189f0050-4f0a-4357-b0d8-72653cdbe698","id":"2","progressId":"hot.restart","finished":true}}]
Restarted application in 852ms.
[{"id":2,"result":{"code":0,"message":""}}