Android5.0之后,网络framework出现很大的变化,原生支持了以太网,并且支持多个网络同时连接同时存在。
Android5.0上面,并不是简单的网络共存,而是每个网络有一套自己的dns,网关,路由表。比如eth0,wlan0分别有自己独立的一套。应用层在建立socket连接的时候,可以自由选择使用那套网络。
下面看看Android是如何实现上述功能的
1. 独立保存的网络参数
Android5.0中引入和netid的概念,用它来标示不同的网络。ConnectivityService是Android的网络总管,负责系统上所有网络管理。当有dns,网关,路由表更新,就会由它设置到系统中并保存下来。
private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId, boolean flush) {
3682 if (oldLp == null || (newLp.isIdenticalDnses(oldLp) == false)) {
3683 Collection<InetAddress> dnses = newLp.getDnsServers();
3684 if (dnses.size() == 0 && mDefaultDns != null) {
3685 dnses = new ArrayList();
3686 dnses.add(mDefaultDns);
3687 if (DBG) {
3688 loge("no dns provided for netId " + netId + ", so using defaults");
3689 }
3690 }
3691 if (DBG) log("Setting Dns servers for network " + netId + " to " + dnses);
3692 try {
3693 mNetd.setDnsServersForNetwork(netId, NetworkUtils.makeStrings(dnses),
3694 newLp.getDomains());
3695 } catch (Exception e) {
3696 loge("Exception in setDnsServersForNetwork: " + e);
3697 }
3698 NetworkAgentInfo defaultNai = mNetworkForRequestId.get(mDefaultRequest.requestId);
3699 if (defaultNai != null && defaultNai.network.netId == netId) {
3700 setDefaultDnsSystemProperties(dnses);
3701 }
3702 flushVmDnsCache();
3703 } else if (flush) {
3704 try {
3705 mNetd.flushNetworkDnsCache(netId);
3706 } catch (Exception e) {
3707 loge("Exception in flushNetworkDnsCache: " + e);
3708 }
3709 flushVmDnsCache();
3710 }
3711 }
updateDnses会调用setDnsServersForNetwork来设置dns
NetworkManagementService.java
public void setDnsServersForNetwork(int netId, String[] servers, String domains) {
1700 mContext.enforceCallingO