您的位置:首页 > 其它

数据业务建立流程之APN参数的激活

2016-09-20 11:52 369 查看
APN参数在前面《数据业务建立流程之常规APN参数的创建》一文中已经都被创建完毕并存入mAllApnSettings的数组中,但是这些APN参数默认都是没有被Enable的,只有当APN被Enable之后,该APN才可以被使用,下面我们就来看如何将一个APN参数激活。

        APN的Enable是通过TelephonyNetworkFactory中的needNetworkFor()方法触发的,我们在《网络连接评分机制之NetworkFactory》文章中介绍过,当当前网络的评分比其他网络高时,就会通过needNetworkFor()方法触发当前网络的建立。比如当前WIFI断开时,如果发现数据网络是打开的,此时就会通过该方法激活数据流量,从而实现从WIFI到数据的转换过程。

        而当needNetworkFor()被触发时,就会引发APN的Enable过程:

[java]
view plain
copy

protected void needNetworkFor(NetworkRequest networkRequest, int score) {  
    //根据网络需求寻找合适APN  
    ApnContext apnContext = apnContextForNetworkRequest(networkRequest);  
    //Enable上网用的APN  
    if (apnContext != null) apnContext.incRefCount();  
}  

        由于不同网络需求可能需要不同的APN参数,因此先要经过apnContextForNetworkRequest()来寻找合适的APN,对于上网来说,其寻找到的APN类型为TYPE_MOBILE,然后通过incRefCount()来Enable当前的APN:

[java]
view plain
copy

@ApnContext.java  
public void incRefCount() {  
    synchronized (mRefCountLock) {  
        if (mRefCount++ == 0) {  
            //设置Enable  
            mDcTracker.setEnabled(mDcTracker.apnTypeToId(mApnType), true);  
        }  
    }  
}  

        这里需要用到DcTracker父类DcTrackerBase中的setEnabled()方法来将APN打开:

[java]
view plain
copy

@DcTrackerBase.java  
protected void setEnabled(int id, boolean enable) {  
    Message msg = obtainMessage(DctConstants.EVENT_ENABLE_NEW_APN);  
    msg.arg1 = id;  
    msg.arg2 = (enable ? DctConstants.ENABLED : DctConstants.DISABLED);  
    sendMessage(msg);  
}  

        这里发送了一条EVENT_ENABLE_NEW_APN的消息,该消息将会在DcTrackerBase中handleMessage()中被处理:

[java]
view plain
copy

@DcTrackerBase.java  
public void handleMessage(Message msg) {  
    switch (msg.what) {  
        case DctConstants.EVENT_ENABLE_NEW_APN:  
            onEnableApn(msg.arg1, msg.arg2);  
            break;  
    }  
}  

        这里的onEnableApn()在子类DcTracker中被覆盖:

[java]
view plain
copy

@DcTracker.java  
protected void onEnableApn(int apnId, int enabled) {  
    ApnContext apnContext = mApnContexts.get(apnIdToType(apnId));  
    if (apnContext == null) {  
        loge("onEnableApn(" + apnId + ", " + enabled + "): NO ApnContext");  
        return;  
    }  
    //打开APN  
    applyNewState(apnContext, enabled == DctConstants.ENABLED, apnContext.getDependencyMet());  
}  

        继续看applyNewState()过程,这里传递的第二个参数为true,第二个参数是从networkAttributes数组中读取的,默认都为true。

[java]
view plain
copy

private void applyNewState(ApnContext apnContext, boolean enabled, boolean met) {  
    boolean cleanup = false;  
    boolean trySetup = false;  
    if (apnContext.isReady()) {  
        //APN如果已经被Enable  
    } else {  
        if (enabled && met) {  
            //APN需要被Enable  
            if (apnContext.isEnabled()) {  
                apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_MET);  
            } else {  
                //设置reason为REASON_DATA_ENABLED  
                apnContext.setReason(Phone.REASON_DATA_ENABLED);  
            }  
            if (apnContext.getState() == DctConstants.State.FAILED) {  
                apnContext.setState(DctConstants.State.IDLE);  
            }  
            trySetup = true;  
        }  
    }  
    //Enable当前APN  
    apnContext.setEnabled(enabled);  
    //设置其mDependencyMet属性也为true  
    apnContext.setDependencyMet(met);  
    //清除当前连接  
    if (cleanup) cleanUpConnection(true, apnContext);  
    //建立数据连接  
    if (trySetup) trySetupData(apnContext);  
}  

        由于enabled、met两个参数此时都为true,因此将会设置APN的Reason为REASON_DATA_ENABLED,并且其mDataEnabled和mDependencyMet属性都为true:

[java]
view plain
copy

public void setEnabled(boolean enabled) {  
    mDataEnabled.set(enabled);  
}  
public void setDependencyMet(boolean met) {  
    mDependencyMet.set(met);  
}  

        再来看一下该APN参数isReady的判断:

[java]
view plain
copy

public boolean isReady() {  
    return mDataEnabled.get() && mDependencyMet.get();  
}  

        由此可知,以后当判断该APN是否isReady()时,将会得到true的状态,也就是说,当前APN已经准备就绪。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: