How to connect to my http//localhost web server from Android Emulator
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Inside the Android emulator, localhost and 127.0.0.1 refer to the emulator's own loopback interface, not your development machine. To reach a web server running on your host computer, replace localhost with the special alias 10.0.2.2. That single change resolves the vast majority of "connection refused" errors during local Android development.
Why localhost Does Not Work in the Emulator
The Android emulator runs as a virtual machine with its own network stack. When code inside the emulator connects to 127.0.0.1, the request stays inside the virtual machine. It never reaches your host OS.
Google's emulator provides 10.0.2.2 as a hard-coded alias that routes traffic through the virtual router to the host machine's loopback address. This is documented in the Android developer guides and is stable across emulator versions.
The Fix: Use 10.0.2.2
If your development API server runs on http://localhost:8080, change every reference in your Android code to http://10.0.2.2:8080.
Retrofit example (Kotlin)
HttpURLConnection example (Kotlin)
OkHttp example (Kotlin)
Making the Base URL Configurable
Hard-coding 10.0.2.2 everywhere is fragile. A better approach is to use a build config field so the base URL changes based on whether you are running on an emulator, a physical device, or in production.
For teams that test on both emulators and physical devices, you can add a product flavor or use a properties file to switch between 10.0.2.2 (emulator) and the machine's LAN IP (physical device).
Ensuring Your Server Is Reachable
Before debugging the Android side, confirm that your server is actually running and accessible on the host.
Step 1: Verify the server is listening
Step 2: Test with curl from the host
If this fails, the problem is on the server side, not the emulator.
Step 3: Check the bind address
Some frameworks bind only to 127.0.0.1 by default, which is fine for emulator access since 10.0.2.2 routes to the host's loopback. But if you also need physical device access, bind to 0.0.0.0:
Step 4: Check firewall rules
On macOS, the built-in firewall can block incoming connections. On Windows, Windows Defender Firewall may block the port. Temporarily disabling the firewall or adding an exception for your development port can help isolate the issue.
Handling Android Cleartext (HTTP) Restrictions
Starting with Android 9 (API 28), cleartext HTTP traffic is blocked by default. If your development server does not use HTTPS, you need to explicitly allow HTTP connections.
Option 1: Allow all cleartext traffic (development only)
Option 2: Network security config (more precise)
The second option is more precise: it allows cleartext only to the emulator host alias, keeping HTTPS enforcement everywhere else. Never carry either setting into a production build without a deliberate security decision.
Host Aliases for Different Emulators
Not every emulator uses the same alias. The correct address depends on which virtualization environment you are running.
| Environment | Host alias | Notes |
| Android Studio Emulator (AVD) | 10.0.2.2 | Standard Google emulator |
| Genymotion | 10.0.3.2 | Different virtual router config |
| Physical device on WiFi | Machine's LAN IP (e.g., 192.168.1.42) | No alias; use actual IP |
| Physical device via USB (adb reverse) | localhost works | Port forwarded through adb |
Using adb reverse for physical devices
For physical devices connected over USB, adb reverse creates a port forward from the device to the host, so localhost works from the device side:
After running this command, code on the physical device can connect to http://localhost:8080 and the request is forwarded to port 8080 on the host machine. This is often the cleanest approach for physical device testing because no IP addresses need to change.
Debugging Connection Issues
When connections still fail after applying the correct alias, work through this checklist:
If ping works but HTTP fails, the issue is typically cleartext restrictions or a firewall rule. If ping also fails, the emulator's network configuration may need to be reset (wipe data and cold boot).
Common Pitfalls
Using localhost or 127.0.0.1 in the emulator. This is the most frequent mistake. Those addresses point to the emulator itself, not the host machine. Replace with 10.0.2.2.
Testing 10.0.2.2 on a physical device. The alias only exists inside the standard Android emulator. Physical devices need either the host's LAN IP or adb reverse.
Forgetting cleartext restrictions on API 28+. The connection silently fails with a generic error. Check logcat for "Cleartext HTTP traffic not permitted" messages.
Server bound to 127.0.0.1 when testing from a physical device. The emulator works because 10.0.2.2 routes to the host's loopback. Physical devices connect over the network, so the server must bind to 0.0.0.0 or the machine's network interface.
Hard-coding the IP instead of using build config. When the app moves from emulator testing to physical device testing to staging, every hard-coded address must change. Use BuildConfig fields or a properties file to manage this cleanly.
Assuming all emulators use the same alias. Genymotion uses 10.0.3.2. Custom AOSP builds may use different addresses entirely. Always verify the alias for your specific emulator.
Summary
- Replace
localhostwith10.0.2.2to reach your host machine from the standard Android emulator. - Configure base URLs through build config rather than hard-coding IP addresses.
- Verify your server is running and listening on the expected port before debugging the Android side.
- Allow cleartext HTTP traffic for development builds when not using HTTPS, preferably scoped to
10.0.2.2only. - Use
adb reversefor physical device testing to avoid IP address management entirely. - Different emulators use different host aliases. Verify the correct address for your environment.

