[Android]エミュレータのhostsファイルを書き換える【Android Studio対応・最新版】

2012年1月26日

Androidエミュレータのhostsファイルを書き換えたいシーンは多い。たとえば、開発中のAPIサーバーをカスタムドメインで参照させたい場合や、特定のドメインをローカルホストに向けてアプリの動作を検証したい場合だ。

本記事では、現在主流のAndroid Studio(AVD Manager)環境でhostsファイルを書き換える方法を、Android 13/14の最新APIレベルに対応した形で解説する。旧来の adb remount ベースの手順が通用しなくなったケースへの対処法も合わせて紹介する。

Androidエミュレータのhostsファイルを書き換える方法


目次

  1. 前提条件と環境
  2. 方法1:-writable-systemオプションを使う(推奨)
  3. 方法2:adb remount を使う(旧来の手順)
  4. 方法3:-dns-serverオプションでDNSレベルで解決する
  5. Android 13/14でのroot取得について
  6. よくあるエラーと対処法
  7. 関連記事

前提条件と環境

作業前に以下を準備する。

  • Android Studio がインストールされていること(Electric Eel以降推奨)
  • Android SDK Platform-Tools がPATHに通っていること(adb コマンドが使えること)
  • 使用するAVD がGoogle Play対応でないイメージ(google_apisdefault 系)であること
  • Google Play Store対応イメージ(google_apis_playstore)はrootが取れないため注意
# adbのバージョン確認
adb version
# Android Debug Bridge version 35.x.x 程度であれば問題なし

方法1:-writable-systemオプションを使う(推奨)

Android Studio 2022以降の環境では、エミュレータ起動時に -writable-system オプションを付けることで、/system パーティションへの書き込みが有効になる。これが現時点でもっとも確実な手順だ。

手順

ステップ1:エミュレータをコマンドラインから起動する

# AVD名の確認
emulator -list-avds

# 出力例:
# Pixel_6_API_33
# Pixel_7_API_34
# writable-systemを有効にして起動
emulator -avd Pixel_6_API_33 -writable-system -no-snapshot-load

-no-snapshot-load を付けることで、前回のスナップショット(書き込み保護状態)をロードせずに起動できる。

Android AVD Manager でシステムイメージを選択する画面

ステップ2:rootとして adb 接続する

adb root

成功すると restarting adbd as root と表示される。

adb remount

成功すると remount succeeded と表示される。

ステップ3:現在のhostsファイルを取得して編集する

# hostsファイルをローカルに取得
adb pull /system/etc/hosts ./hosts_backup

取得したファイルをテキストエディタで編集する。デフォルトの内容は以下の通り:

127.0.0.1       localhost
::1             ip6-localhost

カスタムエントリを追記する例:

127.0.0.1       localhost
::1             ip6-localhost
192.168.1.100   api.myapp.local
10.0.2.2        devserver.local

ポイント: エミュレータから見てホストマシン(開発PC)のIPアドレスは 10.0.2.2 になる。ローカルで動かしているAPIサーバーを参照させたい場合はこのIPを使う。

ステップ4:編集したhostsファイルをプッシュする

# hostsファイルを書き込む
adb push ./hosts_backup /system/etc/hosts

# パーミッションを644に設定する
adb shell chmod 644 /system/etc/hosts

ステップ5:DNSキャッシュをクリアして反映確認する

# DNSキャッシュのクリア(Android 9以降)
adb shell ndc resolver flushdefaultif

# 反映確認(pingで疎通チェック)
adb shell ping -c 1 api.myapp.local

方法2:adb remountを使う(旧来の手順)

Android 12以前のAPIレベル(API 30以下)を使っている場合や、旧来のAOSPイメージを使っている場合はこちらの手順でも動作する。

手順

エミュレータを通常起動した後、以下のコマンドを順番に実行する。

# rootとして再起動
adb root

# /systemを読み書き可能にリマウント
adb remount

# hostsファイルを取得
adb pull /system/etc/hosts ./hosts

# (ファイルを編集する)

# hostsファイルをプッシュ
adb push ./hosts /system/etc/hosts

# パーミッション設定
adb shell chmod 644 /system/etc/hosts

マウントポイントを手動で確認する方法

adb remount が効かない場合は、マウントポイントを直接指定してリマウントする。

adb shell mount

出力例(/system のエントリを探す):

/dev/block/vda /system ext4 ro,seclabel,relatime 0 0

このデバイスパスを使ってリマウントする:

adb shell mount -o rw,remount /dev/block/vda /system

その後、hostsファイルの操作を行う。


方法3:-dns-serverオプションでDNSレベルで解決する

hostsファイルの書き換えではなく、エミュレータが使うDNSサーバー自体を変更する方法もある。ローカルにDNSサーバー(dnsmasqなど)を立てておき、そこにカスタムレコードを定義する手順だ。

hostsファイルを直接書き換えるよりも管理が楽で、Android 13/14のGoogle Playイメージでも使えるメリットがある。

# カスタムDNSサーバーを指定してエミュレータを起動
emulator -avd Pixel_7_API_34 -dns-server 10.0.2.2

ホストマシン側で dnsmasq を動かし、ポート53でリクエストを受け付けるように設定する。

# dnsmasqの設定例(/etc/dnsmasq.conf)
address=/api.myapp.local/192.168.1.100
address=/devserver.local/10.0.2.2

Android 13/14でのroot取得について

Android 13(API 33)・Android 14(API 34)の Google Play Store対応イメージgoogle_apis_playstore)は、セキュリティ強化のためrootが取れない仕様になっている。

adb root
# adbd cannot run as root in production builds

このエラーが出た場合の対処法は以下の通り。

対処法 詳細
Google Play非搭載イメージを使う AVD作成時に Google APIs または AOSP (No Google APIs) を選択する
-dns-server オプションを使う hostsファイルを書き換えずにDNSレベルで解決する
Android Studioのプロキシ設定を使う 特定のURLリライトが目的なら CharlesやmitmproxyをHTTPSプロキシとして設定する方法もある

AVD Manager でAPIレベルとシステムイメージを選択する画面

Google Play非搭載イメージの選び方

Android Studioで新しいAVDを作成する際、「System Image」選択画面で以下のタブを確認する。

  • Recommended:Google Play Store搭載(rootが取れない)
  • Google APIs:Google Playなし、Google APIは使える(rootが取れる)
  • Other Images:AOSPイメージ(Google APIもなし)

hostsファイルの書き換えが必要なら Google APIs タブからイメージを選択することが重要だ。


よくあるエラーと対処法

adb: error: failed to copy: Read-only file system

/system が読み取り専用のままプッシュしようとした場合に発生する。

対処法: -writable-system でエミュレータを再起動し、adb root && adb remount を再実行する。

remount failed: Permission denied

Google Play Store対応イメージでrootなしにremountしようとしている場合に発生する。

対処法: adb root を先に実行するか、Google Play非搭載イメージに切り替える。

adb root 後も /system への書き込みができない

API 33以降のエミュレータでは、-writable-system フラグなしで起動した場合、rootを取っても書き込めないケースがある。

対処法: 必ず -writable-system-no-snapshot-load を付けて起動し直す。

emulator -avd <AVD名> -writable-system -no-snapshot-load

hostsファイルを書き換えても反映されない

DNSキャッシュが残っている、またはアプリが独自のDNSリゾルバを持っている場合に起こる。

対処法:

# DNSキャッシュクリア
adb shell ndc resolver flushdefaultif

# それでも効かない場合はエミュレータを再起動する
adb reboot

関連記事

Android

Posted by GENDOSU