Flutterでアプリの開発中にホスト名でローカルサーバーを参照させるためにhostsファイルを編集する必要が出てきました。hostsファイルの書き換え手順については色々情報があったのですが、hostsがread onlyで書き換えられない問題で暫くハマってしまったので、書き換え時の一連の流れと解決策を書き留めておきます。
ちなみに、Macでは/etc/hostsを書き換えるだけで素直に読み込んでくれますので非常に楽です。Androidエミュレーターもそういう仕様にして欲しいところです。
hostsがread onlyで書き換えられない場合の解決策
最初に解決策ですが、SDK PlatformでAPI28以下のものを使用すればできました。現時点では30と29がありますが、そのどちらでも下記のエラーが出ました。
adb: error: failed to copy 'hosts' to '/system/etc/hosts': remote couldn't create file: Read-only file system
SDK PlatformをAPI28にする
Android studioのConfigureからSDK Managerを開きAndroid 9.0を選択してインストールします(インストールは暫く時間がかかります)
デバイスを登録する
Android studioのConfigureからADV Managerを開き、Create Virtual Deviceからインストールしたデバイスを登録します。
hostsの書き換え手順
以上の手順が完了したらhostsの書き換えに移ります。以下、Windowsの例です。
コマンドプロンプトを開き、エミュレーターをWritableモードで起動する。
> cd C:\Users\ユーザー名\AppData\Local\Android\Sdk\emulator
> emulator -writable-system -avd Pixel_3a_XL_API_28
別のコマンドプロンプトを開き、hostsファイルをダウンロードする。
> cd C:\Users\ユーザー名\AppData\Local\Android\Sdk\platform-tools
> adb root
> adb remount
remount succeeded
> adb pull /system/etc/hosts hosts
/system/etc/hosts: 1 file pulled, 0 skipped. 0.0 MB/s (56 bytes in 0.002s)
この時点でplatform-toolsフォルダにhostsファイルがダウンロードされていると思いますので、最後の行に必要なIPとホスト名を追加します。
hostsファイルを編集したhostsで上書きする。
> adb push hosts /system/etc/hosts
hosts: 1 file pushed, 0 skipped. 0.1 MB/s (99 bytes in 0.001s)
以下のコマンドでhostsが正常に書き換えられたか内容を確認することができます。
> adb shell
> cat /etc/hosts
保存したhostsが元に戻る問題
エミュレーターを再起動するとせっかく変更したhostsファイルが元に戻ってしまいます。これについてはネットで質問している人を見かけましたが、まだ解決策は無いようです。
解決策が見つかったらこの記事で紹介します。面倒ですが、当面はできる限りエミュレーターを起動したままにしておくことで回避することにします。