ConnectivityService与wifi的交互

  • 接着前面说前面写了一篇《Wifi启动流程分析》,大致分析了一下进入Android后wifi的启动情况。在最开始的地方也说了有创建一个ConnectivityService对象来管理一系列数据连接相关的服务。try{Slog.i(TAG,"ConnectivityService");connectivity=newConnectivityService(context,networkManagement,networkStats,networkPolicy)
  • 接着前面说 

    前面写了一篇《Wifi启动流程分析》,大致分析了一下进入Android后wifi的启动情况。在最开始的地方也说了有创建一个ConnectivityService对象来管理一系列数据连接相关的服务。

    try { 
    Slog.i(TAG, "Connectivity Service"); 
    connectivity = new ConnectivityService( 
    context, networkManagement, networkStats, networkPolicy); 
    ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity); 
    networkStats.bindConnectivityManager(connectivity); 
    networkPolicy.bindConnectivityManager(connectivity); 
    wifiP2p.connectivityServiceReady(); 
    wifi.checkAndStartWifi(); 
    } catch (Throwable e) { 
    reportWtf("starting Connectivity Service", e); 

    接下来看看在ConnectivityService的构造方法中做了什么。

    public ConnectivityService(Context context, INetworkManagementService netManager, 
    INetworkStatsService statsService, INetworkPolicyManager policyManager, 
    NetworkFactory netFactory) { 
    if (DBG) log("ConnectivityService starting up"); 
    HandlerThread handlerThread = new HandlerThread("ConnectivityServiceThread"); 
    handlerThread.start(); 
    mHandler = new InternalHandler(handlerThread.getLooper()); 
    mTrackerHandler = new NetworkStateTrackerHandler(handlerThread.getLooper()); 
    if (netFactory == null) { 
    netFactory = new DefaultNetworkFactory(context, mTrackerHandler); 

    ...//此处省略,很多行O(∩_∩)O~ 
    for (int targetNetworkType : mPriorityList) { 
    final NetworkConfig config = mNetConfigs[targetNetworkType]; 
    final NetworkStateTracker tracker; 
    try { 
    tracker = netFactory.createTracker(targetNetworkType, config); 
    mNetTrackers[targetNetworkType] = tracker; 
    } catch (IllegalArgumentException e) { 
    Slog.e(TAG, "Problem creating " + getNetworkTypeName(targetNetworkType) 
    + " tracker: " + e); 
    continue; 

    tracker.startMonitoring(context, mTrackerHandler); 
    if (config.isDefault()) { 
    tracker.reconnect(); 


    .......//省略... 

    这里可以看到,首先创建了一个NetworkStateTrackerHandler:

    mTrackerHandler = new NetworkStateTrackerHandler(handlerThread.getLooper()); 

    一看到Handler,很自然就会想到消息处理,那么这里会处理什么消息呢,先mark一下,等会儿再说。 
    接着往下看,看到创建了一个工厂实例:

    netFactory = new DefaultNetworkFactory(context, mTrackerHandler); 

    既然是工厂类,那么里面必然有很多功能相似的方法集合,具体干嘛的,也在后面说,不要骂我O(∩_∩)O~。 
    接下来,看到一个for循环了,每次循环是创建了一个tracker:

    tracker = netFactory.createTracker(targetNetworkType, config); 

    然后就拿到这个tracker开始监控网络状态:

    tracker.startMonitoring(context, mTrackerHandler); 

    接下来就先不看了,让我们来回头看看这些都是在干嘛的。

    源码分析 

    先来看看创建的netFactory是干嘛的:

    public interface NetworkFactory { 
    public NetworkStateTracker createTracker(int targetNetworkType, NetworkConfig config); 

    private static class DefaultNetworkFactory implements NetworkFactory { 
    private final Context mContext; 
    private final Handler mTrackerHandler; 
    public DefaultNetworkFactory(Context context, Handler trackerHandler) { 
    mContext = context; 
    mTrackerHandler = trackerHandler; 

    @Override 
    public NetworkStateTracker createTracker(int targetNetworkType, NetworkConfig config) { 
    switch (config.radio) { 
    case TYPE_WIFI: 
    return new WifiStateTracker(targetNetworkType, config.name); 
    case TYPE_MOBILE: 
    return new MobileDataStateTracker(targetNetworkType, config.name); 
    case TYPE_DUMMY: 
    return new DummyDataStateTracker(targetNetworkType, config.name); 
    case TYPE_BLUETOOTH: 
    return BluetoothTetheringDataTracker.getInstance(); 
    case TYPE_WIMAX: 
    return makeWimaxStateTracker(mContext, mTrackerHandler); 
    case TYPE_ETHERNET: 
    return EthernetDataTracker.getInstance(); 
    default: 
    throw new IllegalArgumentException( 
    "Trying to create a NetworkStateTracker for an unknown radio type: " 
    + config.radio); 



    这个的代码也比较短,作为ConnectivityService的静态内部类存在。 
    这个工厂类,主要是根据给定的NetworkConfig生成一个NetworkStateTracker实例。 
    可以看到,当类型为wifi时,会创建一个Wifi的状态追踪器:

    new WifiStateTracker(targetNetworkType, config.name); 

    这个正是我们想要的。 
    /frameworks/base/wifi/java/android/net/wifi/WifiStateTracker.java

    public WifiStateTracker(int netType, String networkName) { 
    mNetworkInfo = new NetworkInfo(netType, 0, networkName, ""); 
    mLinkProperties = new LinkProperties(); 
    mLinkCapabilities = new LinkCapabilities(); 
    mNetworkInfo.setIsAvailable(false); 
    setTeardownRequested(false); 

    这个构造方法中也没做很多事情,做了一些初始化的工作。虽然构造方法中没做什么,不过我们知道,这个对象中的一些方法很重要,比如startMonitoring。


    在拿到netFactory对象之后,紧接着就是调用了createTracker方法,针对每种类型的连接创建对应的tracker对象,这个在上面的for循环中可以清晰的看到。像wifi接下来就与WifiStateTracker密切相关。


    在得到tracker对象之后,我们看到每个tracker开始执行自己的监控:

    tracker.startMonitoring(context, mTrackerHandler); 

    上面已经说了,看WifiStateTracker中的方法实现:

    /** 
    * Begin monitoring wifi connectivity 
    */ 
    public void startMonitoring(Context context, Handler target) { 
    mCsHandler = target; 
    mContext = context; 
    mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); 
    IntentFilter filter = new IntentFilter(); 
    filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); 
    filter.addAction(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION); 
    mWifiStateReceiver = new WifiStateReceiver(); 
    mContext.registerReceiver(mWifiStateReceiver, filter); 

    这里注册一个广播接收者,主要监听网络状态变化和链路配置信息的变化。下面是这个广播接收者的实现:

    private class WifiStateReceiver extends BroadcastReceiver { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
    if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { 
    mNetworkInfo = (NetworkInfo) intent.getParcelableExtra( 
    WifiManager.EXTRA_NETWORK_INFO); 
    mLinkProperties = intent.getParcelableExtra( 
    WifiManager.EXTRA_LINK_PROPERTIES); 
    if (mLinkProperties == null) { 
    mLinkProperties = new LinkProperties(); 

    mLinkCapabilities = intent.getParcelableExtra( 
    WifiManager.EXTRA_LINK_CAPABILITIES); 
    if (mLinkCapabilities == null) { 
    mLinkCapabilities = new LinkCapabilities(); 

    // don't want to send redundent state messages 
    // but send portal check detailed state notice 
    NetworkInfo.State state = mNetworkInfo.getState(); 
    if (mLastState == state &;&; 
    mNetworkInfo.getDetailedState() != DetailedState.CAPTIVE_PORTAL_CHECK) { 
    return; 
    } else { 
    mLastState = state; 

    Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, 
    new NetworkInfo(mNetworkInfo)); 
    msg.sendToTarget(); 
    } else if (intent.getAction().equals(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION)) { 
    mLinkProperties = (LinkProperties) intent.getParcelableExtra( 
    WifiManager.EXTRA_LINK_PROPERTIES); 
    Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo); 
    msg.sendToTarget(); 



    最后会通过mCsHandler发送了一个消息,消息由谁来接收呢? 
    前面已经说过mTrackerHandler这个Handler,消息就是传到它这里来了,看看handleMessage方法,代码略长:

    public void handleMessage(Message msg) { 
    NetworkInfo info; 
    switch (msg.what) { 
    case NetworkStateTracker.EVENT_STATE_CHANGED: { 
    info = (NetworkInfo) msg.obj; 
    NetworkInfo.State state = info.getState(); 
    if (VDBG || (state == NetworkInfo.State.CONNECTED) || 
    (state == NetworkInfo.State.DISCONNECTED) || 
    (state == NetworkInfo.State.SUSPENDED)) { 
    log("ConnectivityChange for " + 
    info.getTypeName() + ": " + 
    state + "/" + info.getDetailedState()); 

    if (ConnectivityManager.isNetworkTypeMobile(info.getType()) 
    &;&; (0 != Settings.Global.getInt(mContext.getContentResolver(), 
    Settings.Global.DEVICE_PROVISIONED, 0)) 
    &;&; (((state == NetworkInfo.State.CONNECTED) 
    &;&; (info.getType() == ConnectivityManager.TYPE_MOBILE)) 
    || info.isConnectedToProvisioningNetwork())) { 
    log("ConnectivityChange checkMobileProvisioning for" 
    + " TYPE_MOBILE or ProvisioningNetwork"); 
    checkMobileProvisioning(CheckMp.MAX_TIMEOUT_MS); 

    EventLogTags.writeConnectivityStateChanged( 
    info.getType(), info.getSubtype(), info.getDetailedState().ordinal()); 
    if (info.getDetailedState() == 
    NetworkInfo.DetailedState.FAILED) { 
    log("NetworkInfo.DetailedState.FAILED...."); 
    handleConnectionFailure(info); 
    } else if (info.getDetailedState() == 
    DetailedState.CAPTIVE_PORTAL_CHECK) { 
    handleCaptivePortalTrackerCheck(info); 
    } else if (info.isConnectedToProvisioningNetwork()) { 
    LinkProperties lp = getLinkProperties(info.getType()); 
    if (DBG) { 
    log("EVENT_STATE_CHANGED: connected to provisioning network, lp=" + lp); 

    for (RouteInfo r : lp.getRoutes()) { 
    removeRoute(lp, r, TO_DEFAULT_TABLE); 

    } else if (state == NetworkInfo.State.DISCONNECTED) { 
    handleDisconnect(info); 
    } else if (state == NetworkInfo.State.SUSPENDED) { 
    handleDisconnect(info); 
    } else if (state == NetworkInfo.State.CONNECTED) { 
    log("state == NetworkInfo.State.CONNECTED,then handle connect"); 
    handleConnect(info); 

    if (mLockdownTracker != null) { 
    mLockdownTracker.onNetworkInfoChanged(info); 

    break; 

    case NetworkStateTracker.EVENT_CONFIGURATION_CHANGED: { 
    info = (NetworkInfo) msg.obj; 
    // MStar Android Patch Begin 
    if (info == null) { 
    loge("ERROR: No network info for EVENT_CONFIGURATION_CHANGED "); 
    return; 

    // MStar Android Patch End 
    handleConnectivityChange(info.getType(), false); 
    break; 

    case NetworkStateTracker.EVENT_NETWORK_SUBTYPE_CHANGED: { 
    info = (NetworkInfo) msg.obj; 
    int type = info.getType(); 
    if (mNetConfigs[type].isDefault()) updateNetworkSettings(mNetTrackers[type]); 
    break; 



    这里处理了多种系统网络状态变化,在这里,分析一下 
    EVENT_STATE_CHANGED。当网络状态为state == NetworkInfo.State.CONNECTED时,会执行handleConnect(info); 
    在该方法中,会继续调用handleConnectivityChange(newNetType, false); 
    这个方法的实现比较长,

    private void handleConnectivityChange(int netType, boolean doReset) { 
    int resetMask = doReset ? NetworkUtils.RESET_ALL_ADDRESSES : 0; 
    boolean exempt = ConnectivityManager.isNetworkTypeExempt(netType); 
    /* 
    * If a non-default network is enabled, add the host routes that 
    * will allow it's DNS servers to be accessed. 
    */ 
    handleDnsConfigurationChange(netType);//处理DNS配置变化 
    //....此处省略,以下代码主要处理新连接的网络信息与之前的信息比较 
    if (mNetTrackers[netType].getNetworkInfo().isConnected()) { 
    //当前是已经连接上,获取新接入的链接配置信息 
    newLp = mNetTrackers[netType].getLinkProperties(); 
    if (curLp != null) {//当前链路信息存在 
    if (curLp.isIdenticalInterfaceName(newLp)) { 
    CompareResult car = curLp.compareAddresses(newLp); 
    if ((car.removed.size() != 0) || (car.added.size() != 0)) { 
    for (LinkAddress linkAddr : car.removed) { 
    if (linkAddr.getAddress() instanceof Inet4Address) { 
    resetMask |= NetworkUtils.RESET_IPV4_ADDRESSES; 

    if (linkAddr.getAddress() instanceof Inet6Address) { 
    resetMask |= NetworkUtils.RESET_IPV6_ADDRESSES; 



    } else { 
    resetMask = NetworkUtils.RESET_ALL_ADDRESSES; 


    if (mNetConfigs[netType].isDefault()) {//如果是默认网关 
    handleApplyDefaultProxy(newLp.getHttpProxy()); 


    ... 
    boolean resetDns = updateRoutes(newLp, curLp, mNetConfigs[netType].isDefault(), exempt, newLpPrefered); //更新路由 
    .... 
    if (resetMask != 0 || resetDns) { 
    if (VDBG) log("handleConnectivityChange: resetting"); 
    if (curLp != null) { 
    if (VDBG) log("handleConnectivityChange: resetting curLp=" + curLp); 
    for (String iface : curLp.getAllInterfaceNames()) { 
    if (TextUtils.isEmpty(iface) == false) { 
    if (resetMask != 0) { 
    //modify by dq start 
    LinkProperties tmpLp = getLinkProperties(mActiveDefaultNetwork); 
    if(tmpLp != null) log("current active iface:" + tmpLp.getInterfaceName()); 
    log("ready to reset: " + iface); 
    if(WIFI_ETHERNET_COEXIST_ENABLED 
    &;&; (tmpLp != null) &;&; (iface != null) 
    &;&; (iface.equals(tmpLp.getInterfaceName()))) { 
    // not reset connection 
    log("handleConnectivityChange: netcoexist and network " + 
    mActiveDefaultNetwork +" is active, not reset"); 
    } else { 
    if (DBG) log("resetConnections(" + iface + ", " + resetMask + ")"); 
    // MStar Android Patch Begin 
    // do not reset ppp interface 
    if (iface != null &;&; iface.startsWith("ppp") == false) { 
    NetworkUtils.resetConnections(iface, resetMask);//对网卡重置连接 

    // MStar Android Patch End 
    // Tell VPN the interface is down. It is a temporary 
    // but effective fix to make VPN aware of the change. 
    if ((resetMask &; NetworkUtils.RESET_IPV4_ADDRESSES) != 0) { 
    synchronized(mVpns) { 
    for (int i = 0; i < mVpns.size(); i++) { 
    mVpns.valueAt(i).interfaceStatusChanged(iface, false); 





    //modify by dq end 
    if (resetDns) { 
    flushVmDnsCache();//刷新DNS缓存 
    if (VDBG) log("resetting DNS cache for " + iface); 
    try { 
    mNetd.flushInterfaceDnsCache(iface);//调用netd进程去刷新dns 
    } catch (Exception e) { 
    // never crash - catch them all 
    if (DBG) loge("Exception resetting dns cache: " + e); 


    } else { 
    loge("Can't reset connection for type "+netType); 




    //。。。省略 

    这个方法的代码很长,但是从上面的注释中,我们可以大致看出来是怎样的一种执行过程。

以上是ConnectivityService与wifi的交互的内容,更多 ConnectivityServ 交互 wifi ice 的内容,请您使用右上方搜索功能获取相关信息。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值