Search code examples
androidnetwork-programmingandroid-connectivitymanager

Perform network-specific host name resolutions using Network.getAllByName


In the ConnectivityManager documentation, in bindProcessToNetwork javadoc, there is the following comment :

Using individually bound Sockets created by Network.getSocketFactory().createSocket() and performing network-specific host name resolutions via Network.getAllByName is preferred to calling bindProcessToNetwork.

In OkHttp, there is the setSocketFactory to satisfy the first part of the comment, but I have no idea how/where to use Network.getAllByName to perform the host name resolution.

Any idea how to perform that ?


Solution

  • Ok so I finally find out how to perform that. As I said in my question, I am using OkHttpClient to set my socketfactory. It is the same for the name resolution, using dns (it requires OkHttp3).

    OkHttpClient.Builder httpBuilder = new OkHttpClient.Builder()
        .socketFactory(network.getSocketFactory())
        .dns(NetworkDns.getInstance())
    

    where my NetworkDns class is looking to something like that

    public class NetworkDns implements Dns {
    
      private static NetworkDns sInstance;
      private Network mNetwork;
    
      public static NetworkDns getInstance() {
        if (sInstance == null) {
          sInstance = new NetworkDns();
        }
        return sInstance;
      }
    
      public void setNetwork(Network network) {
        mNetwork = network;
      }
    
      @Override
      public List<InetAddress> lookup(String hostname) throws UnknownHostException {
        if (mNetwork != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
          return Arrays.asList(mNetwork.getAllByName(hostname));
        }
        return SYSTEM.lookup(hostname);
      }
    
      private NetworkDns() {
      }
    }
    

    This way, when network is not null, it will perform the host name resolution on the given network.