Android6.0SystemUI状态栏更新

2024-01-19 05:48

本文主要是介绍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);

} 这个构造方法内部会先去调用一个另外的构造方法;

@VisibleForTestingNetworkControllerImpl(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);//telephonymPhone=telephonyManager;//wifimWifiManager=wifiManager;mLocale=mContext.getResources().getConfiguration().locale;mAccessPoints=accessPointController;mMobileDataController=mobileDataController;mMobileDataController.setNetworkController(this);//TODO:FindawaytomovethisintoMobileDataController.mMobileDataController.setCallback(newMobileDataControllerImpl.Callback(){@OverridepublicvoidonMobileDataEnabled(booleanenabled){mCallbackHandler.setMobileDataEnabled(enabled);}});mWifiSignalController=newWifiSignalController(mContext,mHasMobileDataFeature,mCallbackHandler,this);mEthernetSignalController=newEthernetSignalController(mContext,mCallbackHandler,this);//AIRPLANE_MODE_CHANGEDissentatboot;we'veprobablyalreadymisseditupdateAirplaneMode(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(){@Overridepublicvoidrun(){registerListeners();}};privatevoidregisterListeners(){for(MobileSignalControllermobileSignalController:mMobileSignalControllers.values()){mobileSignalController.registerListener();}if(mSubscriptionListener==null){mSubscriptionListener=newSubListener();}mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);//broadcastsIntentFilterfilter=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()语句;

@VisibleForTestingvoiddoUpdateMobileControllers(){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()方法;

@OverridepublicvoidsetSubs(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()方法;@OverridepublicvoidnotifyListeners(){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(){@Overridepublicvoidrun(){mNetworkController.updateNetworkLabelView();}});} 

调用SignalClusterView.java内的setMobileDataIndicators()方法完成current PhoneState对象的状态刷新,最后调用apply()方法去完成界面上Icon图标的刷新;

@OverridepublicvoidsetMobileDataIndicators(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开发有所帮助.

这篇关于Android6.0SystemUI状态栏更新的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/621426

相关文章

Oracle 通过 ROWID 批量更新表的方法

《Oracle通过ROWID批量更新表的方法》在Oracle数据库中,使用ROWID进行批量更新是一种高效的更新方法,因为它直接定位到物理行位置,避免了通过索引查找的开销,下面给大家介绍Orac... 目录oracle 通过 ROWID 批量更新表ROWID 基本概念性能优化建议性能UoTrFPH优化建议注

Redis中6种缓存更新策略详解

《Redis中6种缓存更新策略详解》Redis作为一款高性能的内存数据库,已经成为缓存层的首选解决方案,然而,使用缓存时最大的挑战在于保证缓存数据与底层数据源的一致性,本文将介绍Redis中6种缓存更... 目录引言策略一:Cache-Aside(旁路缓存)策略工作原理代码示例优缺点分析适用场景策略二:Re

Pandas利用主表更新子表指定列小技巧

《Pandas利用主表更新子表指定列小技巧》本文主要介绍了Pandas利用主表更新子表指定列小技巧,通过创建主表和子表的DataFrame对象,并使用映射字典进行数据关联和更新,实现了从主表到子表的同... 目录一、前言二、基本案例1. 创建主表数据2. 创建映射字典3. 创建子表数据4. 更新子表的 zb

MySQL更新某个字段拼接固定字符串的实现

《MySQL更新某个字段拼接固定字符串的实现》在MySQL中,我们经常需要对数据库中的某个字段进行更新操作,本文就来介绍一下MySQL更新某个字段拼接固定字符串的实现,感兴趣的可以了解一下... 目录1. 查看字段当前值2. 更新字段拼接固定字符串3. 验证更新结果mysql更新某个字段拼接固定字符串 -

MySQL新增字段后Java实体未更新的潜在问题与解决方案

《MySQL新增字段后Java实体未更新的潜在问题与解决方案》在Java+MySQL的开发中,我们通常使用ORM框架来映射数据库表与Java对象,但有时候,数据库表结构变更(如新增字段)后,开发人员可... 目录引言1. 问题背景:数据库与 Java 实体不同步1.1 常见场景1.2 示例代码2. 不同操作

一文详解SQL Server如何跟踪自动统计信息更新

《一文详解SQLServer如何跟踪自动统计信息更新》SQLServer数据库中,我们都清楚统计信息对于优化器来说非常重要,所以本文就来和大家简单聊一聊SQLServer如何跟踪自动统计信息更新吧... SQL Server数据库中,我们都清楚统计信息对于优化器来说非常重要。一般情况下,我们会开启"自动更新

Redis缓存问题与缓存更新机制详解

《Redis缓存问题与缓存更新机制详解》本文主要介绍了缓存问题及其解决方案,包括缓存穿透、缓存击穿、缓存雪崩等问题的成因以及相应的预防和解决方法,同时,还详细探讨了缓存更新机制,包括不同情况下的缓存更... 目录一、缓存问题1.1 缓存穿透1.1.1 问题来源1.1.2 解决方案1.2 缓存击穿1.2.1

Linux Mint Xia 22.1重磅发布: 重要更新一览

《LinuxMintXia22.1重磅发布:重要更新一览》Beta版LinuxMint“Xia”22.1发布,新版本基于Ubuntu24.04,内核版本为Linux6.8,这... linux Mint 22.1「Xia」正式发布啦!这次更新带来了诸多优化和改进,进一步巩固了 Mint 在 Linux 桌面

SpringCloud配置动态更新原理解析

《SpringCloud配置动态更新原理解析》在微服务架构的浩瀚星海中,服务配置的动态更新如同魔法一般,能够让应用在不重启的情况下,实时响应配置的变更,SpringCloud作为微服务架构中的佼佼者,... 目录一、SpringBoot、Cloud配置的读取二、SpringCloud配置动态刷新三、更新@R

Ubuntu 24.04 LTS怎么关闭 Ubuntu Pro 更新提示弹窗?

《Ubuntu24.04LTS怎么关闭UbuntuPro更新提示弹窗?》Ubuntu每次开机都会弹窗提示安全更新,设置里最多只能取消自动下载,自动更新,但无法做到直接让自动更新的弹窗不出现,... 如果你正在使用 Ubuntu 24.04 LTS,可能会注意到——在使用「软件更新器」或运行 APT 命令时,