Short answer
First check the server is running and the port matches by opening the URL in your computer’s browser. On the Android emulator, replace localhost with 10.0.2.2 (http://10.0.2.2:8000). On a real phone, use your computer’s Wi-Fi IP address on the same network, or run adb reverse tcp:8000 tcp:8000 and keep localhost. Start the server on 0.0.0.0, not 127.0.0.1, so it accepts outside connections.
Why the connection is refused, and the fix
01
localhost on the Android emulator
“To access services running on your development machine loopback interface, use the special address 10.0.2.2 instead.” Android Developers, Emulator networking address space
Inside the emulator, 127.0.0.1 is the emulator. Your computer is at a special address. Keep the base URL in one place so it is easy to switch per target.
const baseUrl = String.fromEnvironment( 'API_URL', defaultValue: 'http://10.0.2.2:8000', // Android emulator -> your computer ); // flutter run --dart-define=API_URL=http://192.168.1.20:800002
A real phone
“The pre-allocated addresses of an emulated device are specific to the Android Emulator and are likely to be different on real devices” Android Developers, Emulator networking address space
10.0.2.2 only exists in the emulator. On a phone, use your computer’s IP address on the shared Wi-Fi, or forward the port over USB with adb reverse so localhost on the phone reaches your computer.
adb reverse tcp:8000 tcp:8000 # USB-connected Android device or emulator # or find your computer’s IP: ipconfig getifaddr en0 # macOS03
The server only listens on 127.0.0.1
Dev servers often bind to loopback, so connections from the phone’s IP are refused. Start it on all interfaces, and for Django add the host to ALLOWED_HOSTS.
python manage.py runserver 0.0.0.0:8000 # Django app.listen(8000, '0.0.0.0') // Node and Express uvicorn main:app --host 0.0.0.0 --port 8000
Checked against the vendor’s docs on : Android Developers: Emulator networking address space.
Rather hand it over?
Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.
- from $450App Fix TicketOne reproducible bug in an existing mobile or web app, diagnosed and fixed.See scope and start
- from $450AI-Built App RescueA Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.See scope and start
Related: Flutter “SocketException: Failed host lookup” · Android HTTP requests blocked (cleartext) · Flutter “HandshakeException: CERTIFICATE_VERIFY_FAILED” · Flutter “Connection closed before full header was received”