本文主要是介绍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状态栏更新的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!