Android6.0 SystemUI之网络信号栏显示刷新。Android的网络信号栏的显示刷新也是SystemUI的一部分,主要业务逻辑也是在SystemUI这模块内的,整个流程的开始是在PhoneStatusBar.java内的,
frameworks/base/packages/SystemUI/src/com/Android/systemui/statusbar/phone/PhoneStatusBar.Java;
先从布局方面入手:
由PhoneStatusBar.java的makeStatusBarView()统一加载super_status_bar.xml的。而在Android中,SystemUI上显示信号状态栏的地方主要由三处,分别是状态栏、锁屏界面下的状态栏以及下拉通知栏的快捷设置区域。这三个引用处分别是status_bar.xml、keyguard_status_bar.xml、status_bar_expanded_header.xml;而这三个布局文件都会去include一个system_icons.xml布局,
这个布局就是所要寻找的网络信号栏显示和电池图标显示view的地方。
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical">
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal"/>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="2.5dp"/>
android:layout_width="9.5dp"
android:layout_marginBottom="@dimen/battery_margin_bottom"/>
这个布局又会去include一个signal_cluster_view.xml布局,即这个布局才是具体的信号栏的布局文件
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingEnd="@dimen/signal_cluster_battery_padding"
>
android:id="@+id/vpn"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:paddingEnd="6dp"
android:src="@drawable/stat_sys_vpn_ic"
/>
android:id="@+id/wifi_combo"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
>
android:id="@+id/wifi_signal"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
/>
android:id="@+id/wifi_signal_spacer"
android:layout_width="4dp"
android:layout_height="4dp"
android:visibility="gone"
/>
android:id="@+id/mobile_signal_group"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
>
android:id="@+id/no_sims"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/stat_sys_no_sims"
/>
android:id="@+id/wifi_airplane_spacer"
android:layout_width="4dp"
android:layout_height="4dp"
android:visibility="gone"
/>
android:id="@+id/airplane"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
/>
代码逻辑方面:
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
makeStatusBarView()方法:
在这个方法内先去创建两个控制器mNetworkController、mSecurityController;
mNetworkController=newNetworkControllerImpl(mContext,mHandlerThread.getLooper());
mSecurityController=newSecurityControllerImpl(mContext); NetworkControllerImpl.java继承于BroadcastReceiver,再看下NetworkControllerImpl的构造方法:
publicNetworkControllerImpl(Contextcontext,LooperbgLooper){
this(context,(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE),
(TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE),
(WifiManager)context.getSystemService(Context.WIFI_SERVICE),
SubscriptionManager.from(context),Config.readConfig(context),bgLooper,
newCallbackHandler(),
newAccessPointControllerImpl(context,bgLooper),
newMobileDataControllerImpl(context),
newSubscriptionDefaults());
mReceiverHandler.post(mRegisterListeners);
} 这个构造方法内部会先去调用一个另外的构造方法;
@VisibleForTesting
NetworkControllerImpl(Contextcontext,ConnectivityManagerconnectivityManager,
TelephonyManagertelephonyManager,WifiManagerwifiManager,
SubscriptionManagersubManager,Configconfig,LooperbgLooper,
CallbackHandlercallbackHandler,
AccessPointControllerImplaccessPointController,
MobileDataControllerImplmobileDataController,
SubscriptionDefaultsdefaultsHandler){
mContext=context;
mConfig=config;
mReceiverHandler=newHandler(bgLooper);
mCallbackHandler=callbackHandler;
mSubscriptionManager=subManager;
mSubDefaults=defaultsHandler;
mConnectivityManager=connectivityManager;
mHasMobileDataFeature=
mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
//telephony
mPhone=telephonyManager;
//wifi
mWifiManager=wifiManager;
mLocale=mContext.getResources().getConfiguration().locale;
mAccessPoints=accessPointController;
mMobileDataController=mobileDataController;
mMobileDataController.setNetworkController(this);
//TODO:FindawaytomovethisintoMobileDataController.
mMobileDataController.setCallback(newMobileDataControllerImpl.Callback(){
@Override
publicvoidonMobileDataEnabled(booleanenabled){
mCallbackHandler.setMobileDataEnabled(enabled);
}
});
mWifiSignalController=newWifiSignalController(mContext,mHasMobileDataFeature,
mCallbackHandler,this);
mEthernetSignalController=newEthernetSignalController(mContext,mCallbackHandler,this);
//AIRPLANE_MODE_CHANGEDissentatboot;we'veprobablyalreadymissedit
updateAirplaneMode(true/*forcecallback*/);
} 1、给相应的成员变量赋值;
2、创建handler,mReceiverHandler、mCallbackHandler;
3、创建mMobileDataController控制器,并为其设置回调;
4、创建mWifiSignalController,mEthernetSignalController控制器;
5、检查更新飞行模式;
然后执行完这个内部的构造方法后,接下来会去使用mReceiverHandler去执行一个注册广播的操作,负责监控 wifi, SIM卡状态, service state ,飞行模式等等,最后调用updateMobileControllers()方法初始化一下信号栏显示:
mReceiverHandler.post(mRegisterListeners);
/**
*UsedtoregisterlistenersfromtheBGLooper,thiswaythePhoneStateListenersthat
*getcreatedwillalsorunontheBGLooper.
*/
privatefinalRunnablemRegisterListeners=newRunnable(){
@Override
publicvoidrun(){
registerListeners();
}
};
privatevoidregisterListeners(){
for(MobileSignalControllermobileSignalController:mMobileSignalControllers.values()){
mobileSignalController.registerListener();
}
if(mSubscriptionListener==null){
mSubscriptionListener=newSubListener();
}
mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
//broadcasts
IntentFilterfilter=newIntentFilter();
filter.addAction(WifiManager.RSSI_CHANGED_ACTION);
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
filter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
filter.addAction(TelephonyIntents.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED);
filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
filter.addAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
filter.addAction(ConnectivityManager.INET_CONDITION_ACTION);
filter.addAction(Intent.ACTION_LOCALE_CHANGED);
filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
if(carrier!=null&&(CarrierAppUtils.CARRIER.TELEPHONY_CARRIER_ONE
==carrier)){
filter.addAction(ACTION_EMBMS_STATUS);
}
mContext.registerReceiver(this,filter,null,mReceiverHandler);
mListening=true;
updateMobileControllers();
} 分析完NetworkControllerImpl.java的构造方法之后,基本上我们可以知道NetworkControllerImpl.java是作为信号栏数据控制类,负责监控 wifi, service state ,飞行模式等。
再来看SecurityControllerImpl.java的构造方法,主要先获取一些系统服务的实例,然后再去注册一个用户切换时候的网络回调接口;
publicSecurityControllerImpl(Contextcontext){
mContext=context;
mDevicePolicyManager=(DevicePolicyManager)
context.getSystemService(Context.DEVICE_POLICY_SERVICE);
mConnectivityManager=(ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
mConnectivityManagerService=IConnectivityManager.Stub.asInterface(
ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
mUserManager=(UserManager)
context.getSystemService(Context.USER_SERVICE);
//TODO:re-registernetworkcallbackonuserchange.
mConnectivityManager.registerNetworkCallback(REQUEST,mNetworkCallback);
onUserSwitched(ActivityManager.getCurrentUser());
}
回到PhoneStatusBar.java的makeStatusBarView()方法,接下来实例化自定义的view对象SignalClusterView,上面说过在android SystemUI的三个地方都需要使用网络信号状态栏,所以分别实例化了三次,并为其添加相应的接口。
finalSignalClusterViewsignalCluster=
(SignalClusterView)mStatusBarView.findViewById(R.id.signal_cluster);
finalSignalClusterViewsignalClusterKeyguard=
(SignalClusterView)mKeyguardStatusBar.findViewById(R.id.signal_cluster);
finalSignalClusterViewsignalClusterQs=
(SignalClusterView)mHeader.findViewById(R.id.signal_cluster);
mNetworkController.addSignalCallback(signalCluster);
mNetworkController.addSignalCallback(signalClusterKeyguard);
mNetworkController.addSignalCallback(signalClusterQs);
signalCluster.setSecurityController(mSecurityController);
signalCluster.setNetworkController(mNetworkController);
signalClusterKeyguard.setSecurityController(mSecurityController);
signalClusterKeyguard.setNetworkController(mNetworkController);
signalClusterQs.setSecurityController(mSecurityController);
signalClusterQs.setNetworkController(mNetworkController);
先来看下addSignalCallback()方法,传入的参数为SignalClusterView.java的对象,也就是可以大胆推测这个方法的作用应该就是将SignalClusterView.java和NetworkControllerImpl.java建立callback调用。可以具体来分析下,这个方法的主要实现是在NetworkControllerImpl.java中
publicvoidaddSignalCallback(SignalCallbackcb){
mCallbackHandler.setListening(cb,true);
mCallbackHandler.setSubs(mCurrentSubscriptions);
mCallbackHandler.setIsAirplaneMode(newIconState(mAirplaneMode,
TelephonyIcons.FLIGHT_MODE_ICON,R.string.accessibility_airplane_mode,mContext));
mCallbackHandler.setNoSims(mHasNoSims);
mWifiSignalController.notifyListeners();
mEthernetSignalController.notifyListeners();
for(MobileSignalControllermobileSignalController:mMobileSignalControllers.values()){
mobileSignalController.notifyListeners();
}
}
调用CallbackHandler.setXXX()方法,这些方法主要是通过发送一个msg到handler去执行相应的操作,以setListening()方法为例:
先发送msg为MSG_ADD_REMOVE_SIGNAL的消息到handler:
publicvoidsetListening(SignalCallbacklistener,booleanlistening){
obtainMessage(MSG_ADD_REMOVE_SIGNAL,listening?1:0,0,listener).sendToTarget();
} 在handler中将callback添加到集合中存储起来,完成setListening()方法:
caseMSG_ADD_REMOVE_SIGNAL:
if(msg.arg1!=0){
mSignalCallbacks.add((SignalCallback)msg.obj);
}else{
mSignalCallbacks.remove((SignalCallback)msg.obj);
}
break; 经过对这些setXXX()方法的分析发现,CallBackHandler.java这个类主要是用来NetworkControllerImpl.java与SignalClusterView.java之间的消息传递,二者之间通过NetworkController.SignalCallback接口的回调来实现的;
接下来分别去调用wifi、以太网信号、手机信号控制器的notifyListeners()方法去分别执行初始化信息状态操作。
回到PhoneStatusBar.java的makeStatusBarView()方法,接下来继续调用SignalClusterView.java的方法:
signalCluster.setSecurityController(mSecurityController);
signalCluster.setNetworkController(mNetworkController);
setNetworkController()方法主要是实例化该类的NetworkControllerImpl控制对象;
publicvoidsetNetworkController(NetworkControllerImplnc){
if(DEBUG)Log.d(TAG,"NetworkController="+nc);
mNC=nc;
}
publicvoidsetSecurityController(SecurityControllersc){
if(DEBUG)Log.d(TAG,"SecurityController="+sc);
mSC=sc;
mSC.addCallback(this);
mVpnVisible=mSC.isVpnEnabled();
}
而setSecurityController()方法不仅需要给成员变量赋值,还需要去调用SecurityControllerImpl.java的addCallback()方法,将这个控制器的callback对象添加到集合mCallbacks中保存;
@Override
publicvoidaddCallback(SecurityControllerCallbackcallback){
synchronized(mCallbacks){
if(callback==null||mCallbacks.contains(callback))return;
if(DEBUG)Log.d(TAG,"addCallback"+callback);
mCallbacks.add(callback);
}
} 至此完成信号栏在PhoneStatusBar.java的makeStatusBarView()中执行分析。
信号栏在PhoneStatusBar.java的makeStatusBarView()中的流程执行小结:
1、实例化两个控制器实现对象,NetworkControllerImpl.java、SecurityControllerImpl.java;在NetworkControllerImpl.java的构造方法中去注册相应状态改变的广播,在SecurityControllerImpl.java中注册用户切换时网络状态改变的监听回调;
2、初始化信号栏对象,SignalClusterView.java;
3、通过CallbackHandler.java将NetworkControllerImpl.java和SignalClusterView.java联系起来,中间通过回调的方式来实现NetworkControllerImpl.java对SignalClusterView.java控制通信;
4、SignalClusterView.java调用setSecurityController()来实现SecurityControllerCallback接口,通过回调onStateChanged()方法来实现对切换用户时网络状态改变的监听;
5、NetworkControllerImpl.java是作为信号栏数据控制类,继承于BroadcastReceiver,负责监控 wifi, SIM卡状态, service state ,飞行模式等。
6、SignalClusterView.java用来实现界面的刷新显示;
接下来来分析一下当某些状态发生变化时,SystemUI执行的流程,以插入SIM卡为例:
1、当插SIM卡时,android系统会发送TelephonyIntents.ACTION_SIM_STATE_CHANGED广播;
2、NetworkControllerImpl.java继承于BroadcastReceiver,监听某些相应的系统广播;
3、接收到TelephonyIntents.ACTION_SIM_STATE_CHANGED广播后调用NetworkControllerImpl.java的onReceiver()方法,调用updateMobileControllers()方法;
if(action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)){
//Mighthavedifferentsubscriptionsnow.
updateMobileControllers();
} 4、内部调用doUpdateMobileControllers()方法;
privatevoidupdateMobileControllers(){
if(!mListening){
return;
}
doUpdateMobileControllers();
} 5、获取当前设备内的sim卡信息,如果返回为空,则将此集合置空处理;如果sim卡的订阅信息没有什么变化,则会进入if()语句然后调用updateNoSims()方法然后return;因为当前分析的是插入sim卡,不会进入此if()语句;
@VisibleForTesting
voiddoUpdateMobileControllers(){
Listsubscriptions=mSubscriptionManager.getActiveSubscriptionInfoList();
if(subscriptions==null){
subscriptions=Collections.emptyList();
}
//Iftherehavebeennorelevantchangestoanyofthesubscriptions,wecanleaveasis.
if(hasCorrectMobileControllers(subscriptions)){
//Evenifthecontrollersarecorrect,makesurewehavetherightnosimsstate.
//Suchasonboot,don'tneedanycontrollers,becausetherearenosims,
//butwestillneedtoupdatethenosimstate.
updateNoSims();
return;
}
setCurrentSubscriptions(subscriptions);
updateNoSims();
recalculateEmergency();
}
调用setCurrentSubscriptions()方法;此方法主要是根据返回的sim卡订阅信息集合来构造MobileSignalController,并用集合Map mMobileSignalControllers将其存储起来;
@VisibleForTesting
voidsetCurrentSubscriptions(Listsubscriptions){
Collections.sort(subscriptions,newComparator(){
@Override
publicintcompare(SubscriptionInfolhs,SubscriptionInforhs){
returnlhs.getSimSlotIndex()==rhs.getSimSlotIndex()
?lhs.getSubscriptionId()-rhs.getSubscriptionId()
:lhs.getSimSlotIndex()-rhs.getSimSlotIndex();
}
});
mCurrentSubscriptions=subscriptions;
HashMapcachedControllers=
newHashMap(mMobileSignalControllers);
mMobileSignalControllers.clear();
finalintnum=subscriptions.size();
for(inti=0;i intsubId=subscriptions.get(i).getSubscriptionId();
//Ifwehaveacopyofthiscontrolleralreadyreuseit,otherwisemakeanewone.
if(cachedControllers.containsKey(subId)){
mMobileSignalControllers.put(subId,cachedControllers.remove(subId));
}else{
MobileSignalControllercontroller=newMobileSignalController(mContext,mConfig,
mHasMobileDataFeature,mPhone,mCallbackHandler,
this,subscriptions.get(i),mSubDefaults,mReceiverHandler.getLooper());
mMobileSignalControllers.put(subId,controller);
if(subscriptions.get(i).getSimSlotIndex()==0){
mDefaultSignalController=controller;
}
if(mListening){
controller.registerListener();
}
}
}
if(mListening){
for(Integerkey:cachedControllers.keySet()){
if(cachedControllers.get(key)==mDefaultSignalController){
mDefaultSignalController=null;
}
cachedControllers.get(key).unregisterListener();
}
}
mCallbackHandler.setSubs(subscriptions);
notifyAllListeners();
//TheremaybenewMobileSignalControllersaround,makesuretheygetthecurrent
//inetconditionandairplanemode.
pushConnectivityToSignals();
updateAirplaneMode(true/*force*/);
} MobileSignalController.java这个类主要是用来对信号强度、运营商、网络类型等以及根据这些状态封装对应Icon的控制器,
publicMobileSignalController(Contextcontext,Configconfig,booleanhasMobileData,
TelephonyManagerphone,CallbackHandlercallbackHandler,
NetworkControllerImplnetworkController,SubscriptionInfoinfo,
SubscriptionDefaultsdefaults,LooperreceiverLooper){
super("MobileSignalController("+info.getSubscriptionId()+")",context,
NetworkCapabilities.TRANSPORT_CELLULAR,callbackHandler,
networkController);
mNetworkToIconLookup=newSparseArray<>();
mConfig=config;
mPhone=phone;
mDefaults=defaults;
mSubscriptionInfo=info;
mPhoneStateListener=newMobilePhoneStateListener(info.getSubscriptionId(),
receiverLooper);
mNetworkNameSeparator=getStringIfExists(R.string.status_bar_network_name_separator);
mNetworkNameDefault=getStringIfExists(
com.android.internal.R.string.lockscreen_carrier_default);
mIsDataSignalControlEnabled=mContext.getResources()
.getBoolean(R.bool.config_data_signal_control);
if(mIsDataSignalControlEnabled){
mDataEnabledSettingObserver=
newDataEnabledSettingObserver(newHandler(),context);
mLastState.isForbidden=mCurrentState.isForbidden=
!(isMobileDataEnabled(mSubscriptionInfo.getSubscriptionId()));
}
if(config.readIconsFromXml){
TelephonyIcons.readIconsFromXml(context);
mDefaultIcons=!mConfig.showAtLeast3G?TelephonyIcons.G:TelephonyIcons.THREE_G;
}else{
mapIconSets();
}
if(carrier!=null&&(CarrierAppUtils.CARRIER.TELEPHONY_CARRIER_ONE
==carrier)){
mStyle=context.getResources().getInteger(R.integer.status_bar_style_extended);
}else{
mStyle=context.getResources().getInteger(R.integer.status_bar_style);
}
StringnetworkName=info.getCarrierName()!=null?info.getCarrierName().toString()
:mNetworkNameDefault;
mLastState.networkName=mCurrentState.networkName=networkName;
mLastState.networkNameData=mCurrentState.networkNameData=networkName;
mLastState.enabled=mCurrentState.enabled=hasMobileData;
mLastState.iconGroup=mCurrentState.iconGroup=mDefaultIcons;
//Getinitialdatasimstate.
updateDataSim();
} 1、MobilePhoneStateListener用来监听信号强度、移动数据链接情况等。当检测到信号强度、移动数据连接情况等发生变化的时候会去调用updateTelephony()方法去更新current state设置网络类型、icon、信号强度等等;然后再去调用notifyListenersIfNecessary()方法去调用notifyListeners()方法,通过CallbackHandler对象去调用SignalClusterView.java内的setMobileDataIndicators()方法完成图标的刷新显示;
2、mapIconSets()用来设置网络类型的Icon map集合;
3、此构造方法执行完毕之后会回到NetworkControllerImpl.java的setCurrentSubscriptions()方法,执行controller.registerListener()语句给每一个MobileSignalController对象注册MobilePhoneStateListener监听;
然后调用mCallbackHandler.setSubs()将sim卡的订阅信息集合传给SignalClusterView.java的setSubs()方法。首先会去清除掉之前的mPhoneStates信息和mMobileSignalGroup view,然后再去调用inflatePhoneState()方法;
@Override
publicvoidsetSubs(Listsubs){
if(hasCorrectSubs(subs)){
return;
}
//ClearoutalloldsubIds.
mPhoneStates.clear();
if(mMobileSignalGroup!=null){
mMobileSignalGroup.removeAllViews();
}
finalintn=subs.size();
booleanimsOverWiFi=false;
for(inti=0;i inflatePhoneState(subs.get(i).getSubscriptionId());
imsOverWiFi|=getImsOverWifiStatus(subs.get(i).getSubscriptionId());
}
mImsOverWifi=imsOverWiFi;
if(isAttachedToWindow()){
applyIconTint();
}
} 调用inflatePhoneState()方法重新add state和view;
privatePhoneStateinflatePhoneState(intsubId){
PhoneStatestate=newPhoneState(subId,mContext);
if(mMobileSignalGroup!=null){
mMobileSignalGroup.addView(state.mMobileGroup);
}
mPhoneStates.add(state);
returnstate;
}
然后回到setSubs()方法调用applyIconTint()方法,来设置一些Icon的色彩;
privatevoidapplyIconTint(){
setTint(mVpn,mIconTint);
setTint(mAirplane,mIconTint);
applyDarkIntensity(mDarkIntensity,mNoSims,mNoSimsDark);
applyDarkIntensity(mDarkIntensity,mWifi,mWifiDark);
applyDarkIntensity(mDarkIntensity,mEthernet,mEthernetDark);
for(inti=0;imPhoneStates.get(i).setIconTint(mIconTint,mDarkIntensity);
}
}
继续回到NetworkControllerImpl.java的setCurrentSubscriptions()方法,接下来调用notifyAllListeners()方法来通知mWifiSignalController(wifi)、mEthernetSignalController(以太网)以及所有的mobileSignalController(手机信号)去执行各自的notifyListeners()方法;
notifyAllListeners();
/**
*ForcesupdateofallcallbacksonbothSignalClustersand
*NetworkSignalChangedCallbacks.
*/
privatevoidnotifyAllListeners(){
notifyListeners();
for(MobileSignalControllermobileSignalController:mMobileSignalControllers.values()){
mobileSignalController.notifyListeners();
}
mWifiSignalController.notifyListeners();
mEthernetSignalController.notifyListeners();
} 主要看MobileSignalController.java的notifyListeners()方法,这个方法主要是用来设置当前sim卡属性的显示Icon图像属性;然后通过CallbackHandler对象去调用SignalClusterView.java内的setMobileDataIndicators()方法;
@Override
publicvoidnotifyListeners(){
if(mConfig.readIconsFromXml){
generateIconGroup();
}
MobileIconGroupicons=getIcons();
StringcontentDescription=getStringIfExists(getContentDescription());
StringdataContentDescription=getStringIfExists(icons.mDataContentDescription);
//ShowiconinQSwhenweareconnectedorneedtoshowroaming.
booleanshowDataIcon=false;
if(mContext.getResources().getBoolean(R.bool.show_roaming_and_network_icons)){
showDataIcon=mCurrentState.dataConnected;
}else{
showDataIcon=mCurrentState.dataConnected
||(mCurrentState.iconGroup==TelephonyIcons.ROAMING||isRoaming());
}
IconStatestatusIcon=newIconState(mCurrentState.enabled&&!mCurrentState.airplaneMode,
getCurrentIconId(),contentDescription);
intqsTypeIcon=0;
IconStateqsIcon=null;
Stringdescription=null;
//OnlysenddatasimcallbackstoQS.
if(mCurrentState.dataSim){
qsTypeIcon=showDataIcon?icons.mQsDataType:0;
qsIcon=newIconState(mCurrentState.enabled
&&!mCurrentState.isEmergency,getQsCurrentIconId(),contentDescription);
description=mCurrentState.isEmergency?null:mCurrentState.networkName;
}
booleanactivityIn=mCurrentState.dataConnected
&&!mCurrentState.carrierNetworkChangeMode
&&mCurrentState.activityIn;
booleanactivityOut=mCurrentState.dataConnected
&&!mCurrentState.carrierNetworkChangeMode
&&mCurrentState.activityOut;
if(!mContext.getResources().getBoolean(R.bool.show_roaming_and_network_icons)){
showDataIcon&=mCurrentState.isDefault
||(mCurrentState.iconGroup==TelephonyIcons.ROAMING||isRoaming());
}
showDataIcon&=(mStyle==STATUS_BAR_STYLE_ANDROID_DEFAULT
||mStyle==STATUS_BAR_STYLE_EXTENDED);
inttypeIcon=showDataIcon?icons.mDataType:0;
intdataActivityId=showMobileActivity()?0:icons.mActivityId;
intmobileActivityId=showMobileActivity()?icons.mActivityId:0;
intdataNetworkTypeInRoamingId=0;
if(mStyle==STATUS_BAR_STYLE_EXTENDED&&isRoaming()){
dataNetworkTypeInRoamingId=mCurrentState.dataConnected?typeIcon:0;
typeIcon=TelephonyIcons.ROAMING_ICON;
qsTypeIcon=mCurrentState.dataConnected?qsTypeIcon:0;
}
mCallbackHandler.setMobileDataIndicators(statusIcon,qsIcon,typeIcon,qsTypeIcon,
activityIn,activityOut,dataActivityId,mobileActivityId,
icons.mStackedDataIcon,icons.mStackedVoiceIcon,
dataContentDescription,description,icons.mIsWide,
mSubscriptionInfo.getSubscriptionId(),getImsIconId(),
isImsRegisteredInWifi(),dataNetworkTypeInRoamingId,
getEmbmsIconId());
mCallbackHandler.post(newRunnable(){
@Override
publicvoidrun(){
mNetworkController.updateNetworkLabelView();
}
});
}
调用SignalClusterView.java内的setMobileDataIndicators()方法完成current PhoneState对象的状态刷新,最后调用apply()方法去完成界面上Icon图标的刷新;
@Override
publicvoidsetMobileDataIndicators(IconStatestatusIcon,IconStateqsIcon,intstatusType,
intqsType,booleanactivityIn,booleanactivityOut,intdataActivityId,
intmobileActivityId,intstackedDataId,intstackedVoiceId,
StringtypeContentDescription,Stringdescription,booleanisWide,intsubId){
PhoneStatestate=getState(subId);
if(state==null){
return;
}
state.mMobileVisible=statusIcon.visible&&!mBlockMobile;
state.mMobileStrengthId=statusIcon.icon;
state.mMobileTypeId=statusType;
state.mMobileDescription=statusIcon.contentDescription;
state.mMobileTypeDescription=typeContentDescription;
state.mIsMobileTypeIconWide=statusType!=0&&isWide;
state.mDataActivityId=dataActivityId;
state.mMobileActivityId=mobileActivityId;
state.mStackedDataId=stackedDataId;
state.mStackedVoiceId=stackedVoiceId;
apply();
}
可能在上述操作的过程中,网络连接状态发生了变化,所有最后回到NetworkControllerImpl.java类中继续执行pushConnectivityToSignals()方法将当前的网络连接状态推送给所有的SignalControllers对象控制器。
信号栏总结:
1、由PhoneStatusBar.java的makeStatusBarView()方法来加载布局。由于在Android系统中由三处地方会使用信号栏(状态栏、锁屏界面下的状态栏以及下拉通知栏的快捷设置区域),这三个引用处分别是status_bar.xml、keyguard_status_bar.xml、status_bar_expanded_header.xml),实例化三个对象,并在这个方法中为每一个SignalClusterView.java对象绑定两个控制器对象,NetworkControllerImpl.java、SecurityControllerImpl.java;
2、NetworkControllerImpl.java对象主要是负责作为信号栏数据控制类,继承于BroadcastReceiver,负责监控 wifi, SIM卡状态, service state ,飞行模式等。
SecurityControllerImpl.java对象主要是负责作为用户切换时信号栏数据控制类,负责监控用户切换时的网络状态改变回调;
3、NetworkControllerImpl.java通过CallbackHandler.java将它自己和SignalClusterView.java联系起来,中间通过在CallbackHandler.java的对象中调用SignalClusterView.java的方法来实现NetworkControllerImpl.java对SignalClusterView.java控制通信;
另一方面SignalClusterView.java通过直接实现SecurityController.java的接口来完成通信功能,在SecurityControllerImpl.java通过直接回调onStateChanged()方法通知SignalClusterView.java进行相应的操作;
4、NetworkControllerImpl.java是继承于BroadcastReceiver,通过监听系统广播等来监控SIM卡事件变化等。当插入SIM卡时会获取当前SIM卡的订阅信息集合,然后遍历此集合,为订阅信息再设置一个MobileSignalController.java。
5、MobileSignalController.java类则主要是实现PhoneStateListener接口用来监听service state、信号强度、通话状态、移动数据连接状态,设置相应的显示图标。然后将这些状态和图标显示属性通过CallbackHandler.java传递给SignalClusterView.java对象中。
6、SignalClusterView.java通过调用apply()方法和内部类PhoneState的apply()方法来完成最终的界面刷新。
以上就是Android6.0 SystemUI之网络信号栏显示刷新的全文介绍,希望对您学习和使用Android开发有所帮助.