TvdSettings/src/com/android/settings/ethernet/EthernetSettings.java
类EthernetSettings继承了
--SettingsPreferenceFragment 继承了PreferenceFragment,并且实现了DialogCreatable接口, 这就表示EthernetSettings可以作为一个Fragment放到Activity中.
--Preference.OnPreferenceClickListener 自己处理PreferenceItem的Click事件
--Preference.OnPreferenceChangeListener 自己处理PreferenceItem的Change事件
--DialogInterface.OnClickListener 处理Dialog的事件
--DialogInterface.OnDismissListener 自己处理Dialog的dismiss事件
通过上图可以看出以太网管理界面共有一个开启toggle, 以太网设备列表, 以太网MAC地址, 以太网IP地址, 以太网高级配置, 在源码中对应是,
--CheckBoxPreference mEthEnable 以太网开关
--PreferenceCategory mEthDevices 以太网设备列表
--Preference mMacPreference MAC地址信息
--Preference mIpPreference IP地址信息
--Preference mEthConfigure 以太网配置选项
--EthPreference mSelected 以太网配置窗口
在EthernetSettings的onCreate调用中会初始化这些preference, 对mEthEnable添加setOnPreferenceChangeListenrer监听器(自己), 并获取EthernetManager的一个引用, 用于实际操作以太网设备, 接下来通过EthernetManager获取已经保存的以太网设备info, EthernetManager.getSavedConfig(), 并调用upDeviceList(saveInfo)来更新上图中的以太网设备列表.
在onCreate的结尾处会注册一个receiver, 如下,
mEthStateReceiver = new BroadcastReceiver() {
public void onReceiver(Context context, Intent intent) {
handleEvent(context, intent); // EthernetSettings.handleEvent
}
}
监听的Action有,
mFilter.addAction(EthernetManager.ETHERNET_STATE_CHANGED_ACTION); // 以太网状态改变
mFilter.addAction(EthernetManager.NETWORK_STATE_CHANGED_ACTION); // 以太网网络状态改变
registerReceiver(mEthStateReceiver, mFilter);
|
1. 通过widget操纵网卡
处理mEthEnable的change事件在EthernetSettings.onPreferenceChange函数中, 会将当前被选状态传入,并调用setEthEnabled(boolean)来处理, 在此函数中会创建一个异步Task,
private void setEthEnabled(final boolean enable){
new AsyncTask<Void, Void, Void>(){
protected void onPreExecute(){
//Disable button
//mEthEnable.setSummary(R.string.eth_toggle_summary_opening);
Log.d("ethan", "pre exe");
mEthEnable.setEnabled(false);
mEthConfigure.setEnabled(false);
}
@Override
protected Void doInBackground(Void... unused){
try{
Log.d("ethan", "do exe");
if ((mEthManager.isConfigured() != true) && (enable == true)){
publishProgress(); // 这里调用了publish, 但onProgressUpdate却从来没有执行过.
}else{
mEthManager.setEnabled(enable);
}
Thread.sleep(500); ?? 为什么要睡眠一会, 更长一些有问题吗?
}catch(Exception e){
}
return null;
}
protected void onProgressUpdate(Void... unused){
Log.d("ethan", "update exe");
Preference tmpPre = mEthDevices.getPreference(0);
if( tmpPre instanceof EthPreference){
EthPreference tmpEthPre = (EthPreference)tmpPre;
mEthManager.updateDevInfo(tmpEthPre.getConfigure());
mEthManager.setEnabled(enable);
}
}
protected void onPostExecute(Void unused) {
Log.d("ehtan", "post exe");
mEthConfigure.setEnabled(true); // 这个设置mEthConfigure这个Preference(控件)可被点击
mEthEnable.setChecked(enable); // 根据enable变量值来设置mEthEnable控件状态
// Enable button
mEthEnable.setEnabled(true); // 这个是设置mEthEnable这个Preference(控件)可被点击
}
}.execute();
}
|
在创建了这个AsyncTask匿名类并执行, 和UI线程分开执行, 正常调用AsyncTask的成员函数顺序如下,
-->onPreExecute
-->onInBackground-->在这里调用publishProgress会触发下面回调
-->onProgressUpdate
-->onPostExecute
但在我添加打印, 分析出这个AsyncTask的onProgressUpdate和onPostExecute都没有被调用过, 原因???
在doInBackground中会调用
-->mEthManager.setEnabled(boolean)来开启或关闭以太网. 这个后面要分析到EthernetManager里面, 再到Netd中的CommandListener中处理.
这里分析下EthernetManager中的操作
2. 监听网卡状态, 刷新UI
EthernetSettings中注册了一个BroadcastReceiver, 监听Ethernetl和Network状态的改变事件, 处理函数是EthernetSettings.handleEvent
-->当ETHERNET_STATE_CHANGED_ACTION动作发生, 此事件在插入或移出以太网卡时发生
-->如果额外事件是EVENT_NEWDEV或者EVENT_DEVREM, 则调用upDeviceList函数更新mEthDevices列表, 在这个函数中同样会更新MAC, IP地址.
-->如果额外事件不是以上两个,就没有处理操作.
--> 当以太网的NETWORK_STATE_CHANGED_ACTION动作发生, 当网络连接或断开时发生.
--> 如果是EVENT_CONFIGURATION_SUCCESSED事件, 代表网线连接且dhcp配置成功
--> wifi disable掉, 这是在A20上需要添加的, 因为wifi的自动连接机制
--> 设置mIpPreference为当前以太网配置值
--> 并更新设备列表, 同样更新mMacPreference
--> 更新mEthEnable的显示内容, 在未配置成功时Togle中没有显示MAC的, 在配置好后会添加一行MAC信息的文字段.
--> 如果是EVENT_CONFIGURATION_FAILED事件
--> 更新mIpPreference的summary为 (0.0.0.0)
--> 如果是EVENT_DISCONNECTED
--> 如果当前mEthEnable是被check的, 则更新其summaryOn为未连接
--> 如果没有check, 同样更新summaryOn为未连接, 这个判断好像没什么用, 都是同样动作