背景

Android kitkat 默认已经支持 Ethernet 有线网络,只要稍微配置,便可以直接使用,测试结果,网络浏览器和下载都没有没有问题,而且系统可以做到与 wifi 共存,互相不影响功能,这里简单介绍如何使能 Ethernet,并简要分析其代码和流程。

Linux 配置部分


Linux 需要能够支持有线网络,生成 eth 网络设备节点。

Android 配置

overlay


主要是 overlay 里面添加 Ethernet 网络类型支持:  frameworks/base/core/res/res/values/config.xml 
            "1,1"        "7,1"        "9,1"    

其中 9 对应 Ethernet 的网络类型,其定义在  ConnectivityManager.java 中
    /**     * The Ethernet data connection.  When active, all data traffic     * will use this network type's interface by default     * (it has a default route).     */    public static final int TYPE_ETHERNET    = 9;

init..rc


init 里面需要添加 dhcp 和 ip renew 服务
# DHCPCD# # eth0service dhcpcd_eth0 /system/bin/dhcpcd -ABKL    class main    disabled    oneshot# IP Renew# # eth0service iprenew_eth0 /system/bin/dhcpcd -n    class main    disabled    oneshot

流程分析


ConnectivityService

ConnectivityService 的构造函数里面将会读取 radioAttributes 里面的网络配置
    public ConnectivityService(Context context, INetworkManagementService netManager,            INetworkStatsService statsService, INetworkPolicyManager policyManager,            NetworkFactory netFactory) {        if (DBG) log("ConnectivityService starting up");

        // Load device network attributes from resources        String[] raStrings = context.getResources().getStringArray(                com.android.internal.R.array.radioAttributes);        for (String raString : raStrings) {            RadioAttributes r = new RadioAttributes(raString);            if (VDBG) log("raString=" + raString + " r=" + r);            if (r.mType > ConnectivityManager.MAX_RADIO_TYPE) {                loge("Error in radioAttributes - ignoring attempt to define type " + r.mType);                continue;            }            if (mRadioAttributes[r.mType] != null) {                loge("Error in radioAttributes - ignoring attempt to redefine type " +                        r.mType);                continue;            }            mRadioAttributes[r.mType] = r;        }

根据网络配置数据,将会创建 EthernetDataTracker , 并开始监听 startMonitoring
        // Create and start trackers for hard-coded networks        for (int targetNetworkType : mPriorityList) {            final NetworkConfig config = mNetConfigs[targetNetworkType];            final NetworkStateTracker tracker;            try {                tracker = netFactory.createTracker(targetNetworkType, config);                mNetTrackers[targetNetworkType] = tracker;            } catch (IllegalArgumentException e) {                Slog.e(TAG, "Problem creating " + getNetworkTypeName(targetNetworkType)                        + " tracker: " + e);                continue;            }            tracker.startMonitoring(context, mTrackerHandler);            if (config.isDefault()) {                tracker.reconnect();            }        }


EthernetDataTracker

EthernetDataTracker 将会寻找第一个以 eth 开头的有线网络设备,打开并开始做 dhcp

        eth\\d

        sIfaceMatch = context.getResources().getString(                          com.android.internal.R.string.config_ethernet_iface_regex);        try {            final String[] ifaces = mNMService.listInterfaces();            for (String iface : ifaces) {                if (iface.matches(sIfaceMatch)) {                    mNMService.setInterfaceUp(iface);                    InterfaceConfiguration config = mNMService.getInterfaceConfig(iface);                    if (getEthernetCarrierState(iface) == 1) {                        mIface = iface;                        mLinkUp = true;                        mNetworkInfo.setIsAvailable(true);                        if (config != null && mHwAddr == null) {                            mHwAddr = config.getHardwareAddress();                            if (mHwAddr != null) {                                mNetworkInfo.setExtraInfo(mHwAddr);                            }                        }                    }                    // if a DHCP client had previously been started for this interface, then stop it                    NetworkUtils.stopDhcp(iface);                }            }            reconnect();        } catch (RemoteException e) {            Log.e(TAG, "Could not get list of interfaces " + e);        }

DHCP 成功后,通知NetworkManagementService  网路已经连接,这个时候上层应用便可以开始执行网络操作。
                mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, mHwAddr);                Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);                msg.sendToTarget();

如果有多个网口呢,这个 EthernetDataTracker 显然不能满足要求,必须对其进行扩展。

更多相关文章

  1. AccessibilityService辅助类用法(Android(安卓)中的另类钩子)
  2. Unity3D for Android(安卓)纹理压缩支持
  3. Android(安卓)- 支持不同的设备 - 支持不同的语言
  4. 关于Android原生支持Gif动态图的问题
  5. android的手势识别例子
  6. RK3399: 支持wifi/4g与以太网共存
  7. Android属性动画ValueAnimator源码简单分析
  8. android sdk 各个版本的区别
  9. Android(安卓)-- AppWidget 高级篇

随机推荐

  1. Android(安卓)文件压缩和解压
  2. Android开发过程当中无法获取屏幕…
  3. android刮刮卡效果
  4. android-App Widget Host
  5. Managing Bitmap Memory
  6. android 进度条学习
  7. android 来电去电监听
  8. Android曲线图,柱状图,饼图
  9. Android(安卓)5.0设置全屏无标题
  10. Html.fromHtml deprecated in Android(安