getNetworkInfo

我们一般通过connectivityManager 来检测当前是否有wifi或则mobile 连接。
如下所示:
ConnectivityManager connMgr = (ConnectivityManager)
        getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
boolean isWifiConn = networkInfo.isConnected();
我们来看看ConnectivityManager的getNetworkInfo 实现


xref: /frameworks/base/core/java/android/net/ConnectivityManager.java
739    public NetworkInfo getNetworkInfo(Network network) {
740        try {
741            return mService.getNetworkInfoForNetwork(network);
742        } catch (RemoteException e) {
743            return null;
744        }
745    }


其中mService的赋值
1485    private INetworkManagementService getNetworkManagementService() {
1486        synchronized (this) {
1487            if (mNMService != null) {
1488                return mNMService;
1489            }
1490            IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
1491            mNMService = INetworkManagementService.Stub.asInterface(b);
1492            return mNMService;
1493        }
1494    }


可以看出ConnectivityManager是通过binder调用到ConnectivityService的getNetworkInfoForNetwork
xref: /frameworks/base/services/core/java/com/android/server/ConnectivityService.java
1048    @Override
1049    public NetworkInfo getNetworkInfoForNetwork(Network network) {
1050        enforceAccessPermission();
1051        final int uid = Binder.getCallingUid();
1052        NetworkInfo info = null;
1053        NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
1054        if (nai != null) {
1055            synchronized (nai) {
1056                info = new NetworkInfo(nai.networkInfo);
1057                info = getFilteredNetworkInfo(info, nai.linkProperties, uid);
1058            }
1059        }
1060        return info;
1061    }




1050行check是否ACCESS_NETWORK_STATE 权限,这也是为什么我们要在manifest文件中定义ACCESS_NETWORK_STATE
1443    private void enforceAccessPermission() {
1444        mContext.enforceCallingOrSelfPermission(
1445                android.Manifest.permission.ACCESS_NETWORK_STATE,
1446                "ConnectivityService");
1447    }


在getNetworkInfoForNetwork 中先调用getNetworkAgentInfoForNetwork 获取NetworkAgentInfo
876    private NetworkAgentInfo getNetworkAgentInfoForNetwork(Network network) {
877        if (network == null) {
878            return null;
879        }
880        synchronized (mNetworkForNetId) {
881            return mNetworkForNetId.get(network.netId);
882        }
883    };


881行是mNetworkForNetId 是一个数组,所以我们是根据网络类型在这个数组中找info,那什么时候往这个数组中添加数据呢?
3871    private final SparseArray<NetworkAgentInfo> mNetworkForNetId =
3872            new SparseArray<NetworkAgentInfo>();


可以看到是在handleRegisterNetworkAgent 中调用put函数
3920    private void handleRegisterNetworkAgent(NetworkAgentInfo na) {
3921        if (VDBG) log("Got NetworkAgent Messenger");
3922        mNetworkAgentInfos.put(na.messenger, na);
3923        synchronized (mNetworkForNetId) {
3924            mNetworkForNetId.put(na.network.netId, na);
3925        }
3926        na.asyncChannel.connect(mContext, mTrackerHandler, na.messenger);
3927        NetworkInfo networkInfo = na.networkInfo;
3928        na.networkInfo = null;
3929        updateNetworkInfo(na, networkInfo);
3930    }


而handleRegisterNetworkAgent 又是在处理EVENT_REGISTER_NETWORK_AGENT 也就是在注册网络类型的时候调用的。
   private class InternalHandler extends Handler {
2477        public InternalHandler(Looper looper) {
2478            super(looper);
2479        }
2480
2481        @Override
2482        public void handleMessage(Message msg) {
2483            switch (msg.what) {


2525                case EVENT_REGISTER_NETWORK_AGENT: {
2526                    handleRegisterNetworkAgent((NetworkAgentInfo)msg.obj);
2527                    break;
2528                }
而InternalHandler是在ConnectivityService的构造函数中新建的,所以ConnectivityService是会处理 EVENT_REGISTER_NETWORK_AGENT 来添加网络类型.
625    public ConnectivityService(Context context, INetworkManagementService netManager,
626            INetworkStatsService statsService, INetworkPolicyManager policyManager) {
627        if (DBG) log("ConnectivityService starting up");


640        mHandler = new InternalHandler(mHandlerThread.getLooper());




回到ConnectivityService的getNetworkInfoForNetwork函数中
如果已经注册这个类型,则在getNetworkInfoForNetwork的1056行new 一个NetworkInfo 用于返回
 public NetworkInfo(NetworkInfo source) {
148        if (source != null) {
149            synchronized (source) {
150                mNetworkType = source.mNetworkType;
151                mSubtype = source.mSubtype;
152                mTypeName = source.mTypeName;
153                mSubtypeName = source.mSubtypeName;
154                mState = source.mState;
155                mDetailedState = source.mDetailedState;
156                mReason = source.mReason;
157                mExtraInfo = source.mExtraInfo;
158                mIsFailover = source.mIsFailover;
159                mIsRoaming = source.mIsRoaming;
160                mIsAvailable = source.mIsAvailable;
161            }
162        }
163    }
NetworkInfo的构造函数如上所示,注意的是这里154行会赋值mState = source.mState而我们调用的isConnected也是在NetworkInfo 这个class中实现的
251    public boolean isConnected() {
252        synchronized (this) {
253            return mState == State.CONNECTED;
254        }
255    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值