How to connect your Android emulator to a local web service

In two to three quick steps you can get your app to connect to a web server running on the local machine

Sean Weiser
Livefront
3 min readAug 16, 2021

--

Loading… loading… loading…

Like most applications, the app I work on connects to a web service to send data back and forth between the client and server. Usually, if something goes wrong, I can check the server logs and track down any potential issues. Recently, however, I was in a situation where I needed to be able to debug the server code myself as a request came in to thoroughly test an edge case. After pulling down the code and starting up a local web service, I found myself in a spot I had multiple times before: how do I actually reach the service from my emulator? This guide is intended to help future me, along with anyone else who finds themselves in this position.

Note that the following changes are intended for testing, and should not be merged into any production code.

Step 1: Update your base URL

The first step is to update the base URL of your requests to 10.0.2.2, which is a “[s]pecial alias to your host loopback interface (i.e., 127.0.0.1 on your development machine).” 127.0.0.1 and localhost will not work as a base URL in this situation. Be sure to include the port number (e.g. 10.0.2.2:5000) if the web service is running on a non-standard HTTP port.

Our application uses Retrofit as the HTTP client. Updating the base URL is usually as simple as making the following change:

Retrofit updates

This doesn’t quite work for our application, as we’ll discuss in step 3, but for most apps connecting to a single web service, this should be good enough.

Step 2: Add network_security_config.xml to your project

The next step is to add a file called network_security_config.xml to your application’s res/xml folder:

/res/xml/network_security_config.xml

Without this configuration file, you’ll see the following error when attempting requests:

HTTP FAILED: java.net.UnknownServiceException: CLEARTEXT communication to 10.0.2.2 not permitted by network security policy

The only requirements for the file are to set cleartextTrafficPermitted to true and add the domain 10.0.2.2. See Google’s article on network security configuration for more options.

Finally, update your application’s AndroidManifest.xml to reference the new configuration file:

AndroidManifest.xml

(Optional) Step 3: Configure only specific endpoints to use the local server

As mentioned in step 1, updating the base URL doesn’t quite work for our application. We have many microservices spread out over a handful of servers, each with its own base URL. For each request, we swap out the base URL using an OkHttp Interceptor:

Initial base URL interceptor

Without any changes, each request will continue to have its base URL updated from the new default value (10.0.2.2) to the service-specific URL. To get around this issue, we can add a check to the interceptor to skip reconstructing the URL if a local host is present:

Updated base URL interceptor

We’ll also need to revert the earlier change to the base URL in the Retrofit builder that we made in step 1.

Once those changes are complete, all that’s left is actually specifying the endpoint that should use the local service. Instead of setting the base URL universally when constructing the Retrofit instance, we can temporarily hardcode it in the Retrofit service itself. What was once:

Original Retrofit service

now becomes:

Updated Retrofit service

Only endpoints that need to connect to the local web service should be updated; all others can be left alone.

Once those updates are made start up the local web service, relaunch the application on the emulator, and confirm the desired request is hitting the local machine. In my case, once everything was up and running, I was easily able to debug the problem I originally saw. I just hope I can remember how I did it in the future.

Sean usually keeps pretty good notes at Livefront.

--

--