android網絡代碼主要都在/framewrok/base下面,其中網絡的配置在frameworks\base\core\res\res\values\config.xml中。
1.
在 ConnectivityManager.java 中定義的有以下類型:
public static final int TYPE_MOBILE = 0;
public static final int TYPE_WIFI = 1;
public static final int TYPE_MOBILE_MMS = 2;
public static final int TYPE_MOBILE_SUPL = 3;
public static final int TYPE_MOBILE_DUN = 4;
public static final int TYPE_MOBILE_HIPRI = 5;
public static final int TYPE_WIMAX = 6;
/* 這是在機頂盒上爲android系統添加的網絡類型 */
public static final int TYPE_PPPOE = 7;
public static final int TYPE_ETHERNET = 8;
public static final int TYPE_CABLEMODEM = 9;
2.系統對網絡的判斷大多都是在 ConnectivityService.java中處理的,用戶操做的類是 ConnectivityManager.java 經過aidl訪問
ConnectivityService.java提供的服務。而啓動在SystemServer.java中:
try {
Slog.i(TAG, "Connectivity Service");
connectivity = ConnectivityService.getInstance(context);
ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Connectivity Service", e);
}
3.啓動以後再ConnectivityService構造函數裏會判斷是哪一種類型:
注:這裏我就用Ethernet網線接口分析,cable貓的流程相似網線和wifi的。
...
case ConnectivityManager.TYPE_ETHERNET:
if (DBG) Slog.v(TAG, "Starting Ethernet Service.");
EthernetStateTracker est = new EthernetStateTracker(context, mHandler);
EthernetService ethService = new EthernetService(context, est);
ServiceManager.addService(Context.ETHERNET_SERVICE, ethService);
ethService.startEthernet();
mNetTrackers[ConnectivityManager.TYPE_ETHERNET] = est;
est.startMonitoring();
break;
...
4.new EthernetStateTracker對象時會初始化一個對應的監聽線程和消息handler等:
mMonitor = new EthernetMonitor(this);
mDhcpTarget = new DhcpHandler(dhcpThread.getLooper(), this);
new EthernetService(context, est)會啓動剛開始那個監聽線程,不停的向android_net_ethernet.cpp獲取
String eventName = EthernetNative.waitForEvent();
而後處理,發送對應的消息handleEvent(String ifname,int event)
...
ethService.startEthernet();//這裏會跟着設置網絡獲取模式有dhcp方式和手動設置的靜態方式
---> setEthernetEnabled(2);//方法在EthernetService.java
--->mTracker.startDhcpMode();//startDhcpMode這個方法EthernetStateTracker.java
...
est.startMonitoring();//真正啓動,reset下
--->resetInterface();
--->mInterfaceName = info.getIfName();//獲得設備名字如:eth0
若是以前的有地址,這發送消息remove掉
mDhcpTarget.removeMessages(EVENT_DHCP_START);
以後從新配置:
configureInterface(info);
這個接口裏有2種方式:
if (info.getConnectMode().equals(EthernetDevInfo.ETHERNET_CONN_MODE_DHCP)) {
Slog.i(TAG, "trigger dhcp for device " + info.getIfName());
mDhcpTarget.sendEmptyMessage(EVENT_DHCP_START);
} else {
//手動配置
}
配置完了以後發送一個消息
this.sendEmptyMessage(event);
這個消息處理在handleMessage裏。注意這裏下面還有一個DhcpHandler內部類也是消息處理,區分時看前面的調用對象
5.此時,java部分配置已大部分完成,而那個Monitor監聽線程在不停的獲取
EthernetNative.waitForEvent();
到C++層
android_net_ethernet_waitForEvent中獲得,返回形式如:eth0:20:
20表示connected,而後發送成功消息:
case EVENT_INTERFACE_CONFIGURATION_SUCCEEDED:
Slog.i(TAG, "received configured succeeded, stack=" + mStackConnected + " HW=" + mHWConnected);
/**send enabled*/
final Intent succIntent = new Intent(EthernetManager.ETHERNET_STATE_CHANGED_ACTION);
succIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
succIntent.putExtra(EthernetManager.EXTRA_ETHERNET_STATE, EthernetManager.ETHERNET_STATE_ENABLED);
mContext.sendStickyBroadcast(succIntent);
mStackConnected = true;
if (mHWConnected)
setEthState(true, msg.what);
若是mHWConnected這個值爲true的話:
private void setEthState(boolean state, int event) {
Slog.d(TAG,"mNetworkInfo.isConnected() = "+mNetworkInfo.isConnected() +"state = "+state);
if (mNetworkInfo.isConnected() != state) {
if (state) {
setDetailedState(DetailedState.CONNECTED);
//mTarget.sendEmptyMessage(EVENT_CONFIGURATION_CHANGED);
Message msg = mTarget.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
msg.sendToTarget();
} else {
setDetailedState(DetailedState.DISCONNECTED);
stopInterface(true);
}
mNetworkInfo.setIsAvailable(state);
postNotification(event);
}
}
6.以後回到ConnectivityService.java中,會發送一個消息爲NetworkStateTracker.EVENT_STATE_CHANGED調用
else if (state == NetworkInfo.State.CONNECTED) {
handleConnect(info);
}
................ 大體就這樣,若是cable modem或wifi獲取的應該差很少 O(∩_∩)O~