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
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:
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:
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:
(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:
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:
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:
now becomes:
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.