Android6.0SystemUI状态栏更新

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开发有所帮助.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值