Android源码笔记--网络
Posted ljt2724960661
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android源码笔记--网络相关的知识,希望对你有一定的参考价值。
这一节主要了解ConnectivityService,这个api在android网络里使用较常见,它是Android网络管理的中心,它是在SystemServer中创建的,代码如下:
/frameworks/base/services/java/com/android/server/SystemServer.java
/**
* Starts a miscellaneous grab bag of stuff that has yet to be refactored and organized.
*/
private void startOtherServices(@NonNull TimingsTraceAndSlog t)
try
connectivity = new ConnectivityService(
context, networkManagement, networkStats, networkPolicy);
ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity,
/* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL);
networkPolicy.bindConnectivityManager(connectivity);
catch (Throwable e)
reportWtf("starting Connectivity Service", e);
分析:初始化过程ConnectivityService的构造方法非常长,如下:
@VisibleForTesting
protected ConnectivityService(Context context, INetworkManagementService netManager,
INetworkStatsService statsService, INetworkPolicyManager policyManager,
IDnsResolver dnsresolver, IpConnectivityLog logger, INetd netd, Dependencies deps)
if (DBG) log("ConnectivityService starting up");
...
mDefaultRequest = createDefaultInternetRequestForTransport(-1, NetworkRequest.Type.REQUEST);
mNetworkRanker = new NetworkRanker();
NetworkRequestInfo defaultNRI = new NetworkRequestInfo(null, mDefaultRequest, new Binder());
mNetworkRequests.put(mDefaultRequest, defaultNRI);
mNetworkRequestInfoLogs.log("REGISTER " + defaultNRI);
mDefaultMobileDataRequest = createDefaultInternetRequestForTransport(
NetworkCapabilities.TRANSPORT_CELLULAR, NetworkRequest.Type.BACKGROUND_REQUEST);
...
mDefaultWifiRequest = createDefaultInternetRequestForTransport(
NetworkCapabilities.TRANSPORT_WIFI, NetworkRequest.Type.BACKGROUND_REQUEST);
mHandlerThread = mDeps.makeHandlerThread();
mHandlerThread.start();
mHandler = new InternalHandler(mHandlerThread.getLooper());
mTrackerHandler = new NetworkStateTrackerHandler(mHandlerThread.getLooper());
mConnectivityDiagnosticsHandler =
new ConnectivityDiagnosticsHandler(mHandlerThread.getLooper());
mReleasePendingIntentDelayMs = Settings.Secure.getInt(context.getContentResolver(),
Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, 5_000);
mLingerDelayMs = mSystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS);
mNMS = Objects.requireNonNull(netManager, "missing INetworkManagementService");
mStatsService = Objects.requireNonNull(statsService, "missing INetworkStatsService");
mPolicyManager = Objects.requireNonNull(policyManager, "missing INetworkPolicyManager");
mPolicyManagerInternal = Objects.requireNonNull(
LocalServices.getService(NetworkPolicyManagerInternal.class),
"missing NetworkPolicyManagerInternal");
mDnsResolver = Objects.requireNonNull(dnsresolver, "missing IDnsResolver");
mProxyTracker = mDeps.makeProxyTracker(mContext, mHandler);
mNetd = netd;
mKeyStore = KeyStore.getInstance();
mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
mLocationPermissionChecker = new LocationPermissionChecker(mContext);
...
try
mPolicyManager.registerListener(mPolicyListener);
catch (RemoteException e)
// ouch, no rules updates means some processes may never get network
loge("unable to register INetworkPolicyListener" + e);
final PowerManager powerManager = (PowerManager) context.getSystemService(
Context.POWER_SERVICE);
mNetTransitionWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mNetTransitionWakeLockTimeout = mContext.getResources().getInteger(
com.android.internal.R.integer.config_networkTransitionTimeout);
mPendingIntentWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mNetConfigs = new NetworkConfig[ConnectivityManager.MAX_NETWORK_TYPE+1];
...
boolean wifiOnly = mSystemProperties.getBoolean("ro.radio.noril", false);
log("wifiOnly=" + wifiOnly);
String[] naStrings = context.getResources().getStringArray(
com.android.internal.R.array.networkAttributes);
for (String naString : naStrings)
try
NetworkConfig n = new NetworkConfig(naString);
if (VDBG) log("naString=" + naString + " config=" + n);
if (n.type > ConnectivityManager.MAX_NETWORK_TYPE)
continue;
if (wifiOnly && ConnectivityManager.isNetworkTypeMobile(n.type))
continue;
if (mNetConfigs[n.type] != null)
continue;
mLegacyTypeTracker.addSupportedType(n.type);
mNetConfigs[n.type] = n;
mNetworksDefined++;
catch(Exception e)
// ignore it - leave the entry null
if (mNetConfigs[TYPE_VPN] == null)
mLegacyTypeTracker.addSupportedType(TYPE_VPN);
mNetworksDefined++; // used only in the log() statement below.
...
if (mNetConfigs[TYPE_ETHERNET] == null && mDeps.hasService(Context.ETHERNET_SERVICE))
mLegacyTypeTracker.addSupportedType(TYPE_ETHERNET);
mNetworksDefined++;
if (VDBG) log("mNetworksDefined=" + mNetworksDefined);
mProtectedNetworks = new ArrayList<Integer>();
int[] protectedNetworks = context.getResources().getIntArray(
com.android.internal.R.array.config_protectedNetworks);
for (int p : protectedNetworks)
if ((mNetConfigs[p] != null) && (mProtectedNetworks.contains(p) == false))
mProtectedNetworks.add(p);
else
if (DBG) loge("Ignoring protectedNetwork " + p);
mWolSupportedInterfaces = new ArraySet(
mContext.getResources().getStringArray(
com.android.internal.R.array.config_wakeonlan_supported_interfaces));
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
mPermissionMonitor = new PermissionMonitor(mContext, mNetd);
...
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_USER_STARTED);
intentFilter.addAction(Intent.ACTION_USER_STOPPED);
intentFilter.addAction(Intent.ACTION_USER_ADDED);
intentFilter.addAction(Intent.ACTION_USER_REMOVED);
intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
mContext.registerReceiverAsUser(
mIntentReceiver,
UserHandle.ALL,
intentFilter,
null /* broadcastPermission */,
mHandler);
mContext.registerReceiverAsUser(mUserPresentReceiver, UserHandle.SYSTEM,
new IntentFilter(Intent.ACTION_USER_PRESENT), null, null);
// Listen to package add and removal events for all users.
intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
intentFilter.addDataScheme("package");
mContext.registerReceiverAsUser(
mIntentReceiver,
UserHandle.ALL,
intentFilter,
null /* broadcastPermission */,
mHandler);
try
mNMS.registerObserver(mDataActivityObserver);
catch (RemoteException e)
loge("Error registering observer :" + e);
mSettingsObserver = new SettingsObserver(mContext, mHandler);
registerSettingsCallbacks();
final DataConnectionStats dataConnectionStats = new DataConnectionStats(mContext, mHandler);
dataConnectionStats.startMonitoring();
mKeepaliveTracker = new KeepaliveTracker(mContext, mHandler);
mNotifier = new NetworkNotificationManager(mContext, mTelephonyManager,
mContext.getSystemService(NotificationManager.class));
final int dailyLimit = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT,
LingerMonitor.DEFAULT_NOTIFICATION_DAILY_LIMIT);
final long rateLimit = Settings.Global.getLong(mContext.getContentResolver(),
Settings.Global.NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS,
LingerMonitor.DEFAULT_NOTIFICATION_RATE_LIMIT_MILLIS);
mLingerMonitor = new LingerMonitor(mContext, mNotifier, dailyLimit, rateLimit);
mMultinetworkPolicyTracker = mDeps.makeMultinetworkPolicyTracker(
mContext, mHandler, () -> rematchForAvoidBadWifiUpdate());
mMultinetworkPolicyTracker.start();
mMultipathPolicyTracker = new MultipathPolicyTracker(mContext, mHandler);
mDnsManager = new DnsManager(mContext, mDnsResolver, mSystemProperties);
registerPrivateDnsSettingsCallbacks();
执行过程大体如下:
(1)创建处理消息的线程并启动。
(2)创建处理消息的Handle对象mHandler、mTrackerHandler。
(3)创建DefaultNetworkFactory 对象,用来创建各种NetworkStateTracker对象。
(4)使用Android的ID设置net.hostname属性。这个属性将作为网络传输中的主机名。
(5)从Setting 中或者系统资源Config.xml 的config_default_dns_server 项中得到DNS 服务器的IP地址,保存到变量mDefaultDns 中。
(6)保存对其他系统服务的引用,包括NetworkManagementService、NetworkPolicyManagerService、PowerManagerService 和 PhoneInterfaceManager。
(7)创建 wakelock对象mNetTransitionWakeLock,在网络有数据传输时用来防止休眠。
(8)创建NetworkStateTracker对象的数组。
(9)从系统资源Config.xml读取RadioAttributes、networkAttributes、config_protectedNetworks数组的值,分别用来初始化数组变量mRadioAttributes、mNetConfigs和mProtectedNetworks。
(10)根据mNetConfigs数组,计算各种网络类型的优先级,保存在mPriorityList列表中。
(11)变量mNetworkPreference表示系统中优先使用的网络,如果用户在Setting程序中设置了优先网络,则使用用户设置的值;用户没有设置,则从mPriorityList列表按照从先到后的顺序
挑选当前有效的网络类型。
(12)创建各种网络连接的NetworkState Tracker对象,填充mNetTrackers数组。
(13)创建Tethering对象mTethering,用来共享网络。
(14)创建监听用户状态变化 Intent的Receiver对象。
(15)创建Nat464Xlat对象mClat,用于IPV4和IPV6地址的转换。
网络经常会用到的场景是获取当前网络类型,一般使用如下:
public static int getNetworkState(Context context)
ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); // 获取网络服务
if (null == connManager) // 为空则认为无网络
return NETWORK_NONE;
// 获取网络类型,如果为空,返回无网络
NetworkInfo activeNetInfo = connManager.getActiveNetworkInfo();
if (activeNetInfo == null || !activeNetInfo.isAvailable())
return NETWORK_NONE;
return activeNetInfo.getType();
看看源码:
/frameworks/base/core/java/android/net/ConnectivityManager.java
private final IConnectivityManager mService;
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
@Nullable
public Network getActiveNetwork()
try
return mService.getActiveNetwork();
catch (RemoteException e)
throw e.rethrowFromSystemServer();
/frameworks/base/core/java/android/net/IConnectivityManager.aidl
interface IConnectivityManager
Network getActiveNetwork();
Network getActiveNetworkForUid(int uid, boolean ignoreBlocked);
@UnsupportedAppUsage
NetworkInfo getActiveNetworkInfo();
NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked);
@UnsupportedAppUsage(maxTargetSdk = 28)
NetworkInfo getNetworkInfo(int networkType);
/frameworks/base/services/core/java/com/android/server/ConnectivityService.java
@Override
public NetworkInfo getNetworkInfo(int networkType)
enforceAccessPermission();
final int uid = Binder.getCallingUid();
if (getVpnUnderlyingNetworks(uid) != null)
// A VPN is active, so we may need to return one of its underlying networks. This
// information is not available in LegacyTypeTracker, so we have to get it from
// getUnfilteredActiveNetworkState.
final NetworkState state = getUnfilteredActiveNetworkState(uid);
if (state.networkInfo != null && state.networkInfo.getType() == networkType)
filterNetworkStateForUid(state, uid, false);
return state.networkInfo;
final NetworkState state = getFilteredNetworkState(networkType, uid);
return state.networkInfo;
private NetworkState getFilteredNetworkState(int networkType, int uid)
if (mLegacyTypeTracker.isTypeSupported(networkType))
final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
final NetworkState state;
if (nai != null)
state = nai.getNetworkState();
state.networkInfo.setType(networkType);
else
final NetworkInfo info = new NetworkInfo(networkType, 0,
getNetworkTypeName(networkType), "");
info.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null);
info.setIsAvailable(true);
final NetworkCapabilities capabilities = new NetworkCapabilities();
capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING,
!info.isRoaming());
state = new NetworkState(info, new LinkProperties(), capabilities,
null, null, null);
filterNetworkStateForUid(state, uid, false);
return state;
else
return NetworkState.EMPTY;
/frameworks/base/core/java/android/net/LinkProperties.java
//网络连接相关属性在此设置
public final class LinkProperties implements Parcelable
@TestApi
public LinkProperties(@Nullable LinkProperties source, boolean parcelSensitiveFields)
mParcelSensitiveFields = parcelSensitiveFields;
if (source == null) return;
mIfaceName = source.mIfaceName;
mLinkAddresses.addAll(source.mLinkAddresses);
mDnses.addAll(source.mDnses);
mValidatedPrivateDnses.addAll(source.mValidatedPrivateDnses);
mUsePrivateDns = source.mUsePrivateDns;
mPrivateDnsServerName = source.mPrivateDnsServerName;
mPcscfs.addAll(source.mPcscfs);
mDomains = source.mDomains;
mRoutes.addAll(source.mRoutes);
mHttpProxy = (source.mHttpProxy == null) ? null : new ProxyInfo(source.mHttpProxy);
for (LinkProperties l: source.mStackedLinks.values())
addStackedLink(l);
setMtu(source.mMtu);
setDhcpServerAddress(source.getDhcpServerAddress());
mTcpBufferSizes = source.mTcpBufferSizes;
mNat64Prefix = source.mNat64Prefix;
mWakeOnLanSupported = source.mWakeOnLanSupported;
mCaptivePortalApiUrl = source.mCaptivePortalApiUrl;
mCaptivePortalData = source.mCaptivePortalData;
以上是关于Android源码笔记--网络的主要内容,如果未能解决你的问题,请参考以下文章