关闭

网络连接评分机制之再谈WIFI与数据切换过程(原)

标签: NetworkAgentNetworkInfoConnectivityServiceConnectivityManagerNetworkFactory
3052人阅读 评论(5) 收藏 举报
分类:
        前面几节介绍了网络评分机制的运行流程,下面我们再次通过案例来梳理一下评分机制在使用过程中的体现。
        用户原本在用数据上网,但是如果到了一个有WIFI的环境,并连接上了WIFI,此时用户的手机将会自动断开数据网络,这是如何做到的呢?
        当用户来到WIFI环境时,如果连上了某个WIFI,那么此时的WIFI状态机将会进入L2ConnectedState状态,然后会更新当前NetworkInfo状态为CONNECTING状态,并用该NetworkInfo创建WIFI的NetworkAgent对象,同时标明当前WIFI分值为60。即:
            mNetworkAgent = new WifiNetworkAgent(getHandler().getLooper(), mContext, "WifiNetworkAgent", mNetworkInfo, mNetworkCapabilitiesFilter, mLinkProperties, 60);
        然后在NetworkAgent初始化过程中将会向ConnectivityService注册,然后ConnectivityService就会创建WIFI的NetworkAgentInfo对象:
            NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
                new NetworkInfo(networkInfo), new LinkProperties(linkProperties),
                new NetworkCapabilities(networkCapabilities), currentScore, mContext, mTrackerHandler,
                new NetworkMisc(networkMisc));
        然后ConnectivityService将会在handleRegisterNetworkAgent方法中更新当前WIFI的NetworkAgentInfo为CONNECTED状态,并向NetworkMonitor发送连接成功的消息,然后经过有效性检测,WIFI的分值将会保持在60分
        然后在rematchNetworkAndRequests中,将发现现有的网络请求所使用的数据流量方案的分值(50分)低于WIFI的分值,将会把最新WIFI的分值通过sendUpdatedScoreToFactories发送到各个NetworkFactory中,其中就包括数据网络:
        private void sendUpdatedScoreToFactories(NetworkRequest networkRequest, int score) {
            for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
                nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score, 0, networkRequest);
            }
        }
        此时数据网络会再次进行分值对比,并发现自己的分值的确低于目标WIFI分值
        private void evalRequest(NetworkRequestInfo n) {
            if (n.requested == false && n.score < mScore &&
                    n.request.networkCapabilities.satisfiedByNetworkCapabilities(
                        mCapabilityFilter) && acceptRequest(n.request, n.score)) {
                needNetworkFor(n.request, n.score);
                n.requested = true;
            } else if (n.requested == true &&
                    (n.score > mScore || n.request.networkCapabilities.satisfiedByNetworkCapabilities(mCapabilityFilter) == false || acceptRequest(n.request, n.score) == false)) {
                releaseNetworkFor(n.request);
                n.requested = false;
            }
        }
        然后数据网络就进行releaseNetworkFor操作
        @DcTracker.java
        protected void releaseNetworkFor(NetworkRequest networkRequest) {
            ApnContext apnContext = apnContextForNetworkRequest(networkRequest);
            if (apnContext != null) apnContext.decRefCount();
        }
        而APN参数被删掉时将会触发数据业务的关闭
        @ApnContext.java
        public void decRefCount() {
            synchronized (mRefCountLock) {
                if (mRefCount-- == 1) {
                    //关闭数据业务
                    mDcTracker.setEnabled(mDcTracker.apnTypeToId(mApnType), false);
                }
            }
        }
        然后数据业务就被关闭,从而完成网络切换的任务。
3
0

猜你在找
深度学习基础与TensorFlow实践
【在线峰会】前端开发重点难点技术剖析与创新实践
【在线峰会】一天掌握物联网全栈开发之道
【在线峰会】如何高质高效的进行Android技术开发
机器学习40天精英计划
Python数据挖掘与分析速成班
微信小程序开发实战
JFinal极速开发企业实战
备战2017软考 系统集成项目管理工程师 学习套餐
Python大型网络爬虫项目开发实战(全套)
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:259361次
    • 积分:3166
    • 等级:
    • 排名:第10162名
    • 原创:63篇
    • 转载:0篇
    • 译文:0篇
    • 评论:95条
    最新评论