一.界面分析
代码库:
/frameworks/base/services //services.jar
/frameworks/base/packages/SystemUI //SystemUI.apk
在SystemServer.java中调用startSystemUi启动
intent.setComponent(new ComponentName("com.android.systemui",
"com.android.systemui.SystemUIService")); //启动SystemUIService,第一个参数为包名,第二个为Activity
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
context.startServiceAsUser(intent, UserHandle.SYSTEM);
windowManager.onSystemUiStarted();
windowManager.onSystemUiStarted();//启动锁屏界面
SystemUIService的OnCreate会调用((SystemUIApplication) getApplication()).startServicesIfNeeded();
查看startServicesIfNeeded
public void startServicesIfNeeded() {
String[] names = getResources().getStringArray(R.array.config_systemUIServiceComponents); //加载config_systemUIServiceComponents
startServicesIfNeeded(names);//启动
}
config_systemUIServiceComponents位于/frameworks/base/packages/SystemUI/res/values/config.xml,定义了各个activity,这些activity 均继承SystemUI.java
<string-array name="config_systemUIServiceComponents" translatable="false">
<item>com.android.systemui.Dependency$DependencyCreator</item>
<item>com.android.systemui.util.NotificationChannels</item> //创建SystemUI的通知Channel
<item>com.android.systemui.statusbar.CommandQueue$CommandQueueStart</item>
<item>com.android.systemui.keyguard.KeyguardViewMediator</item> //锁屏
<item>com.android.systemui.recents.Recents</item> //最近任务
<item>com.android.systemui.volume.VolumeUI</item> //音量
<item>com.android.systemui.stackdivider.Divider</item> //分屏
<item>com.android.systemui.SystemBars</item> //状态栏
<item>com.android.systemui.usb.StorageNotification</item>
<item>com.android.systemui.power.PowerUI</item> //电量
<item>com.android.systemui.media.RingtonePlayer</item> //铃声播放
<item>com.android.systemui.keyboard.KeyboardUI</item> //锁屏
<item>com.android.systemui.pip.PipUI</item> //画中画
<item>com.android.systemui.shortcut.ShortcutKeyDispatcher</item> //手机屏幕屏切圆角,模拟刘海屏
<item>@string/config_systemUIVendorServiceComponent</item>
<item>com.android.systemui.util.leak.GarbageMonitor$Service</item>
<item>com.android.systemui.LatencyTester</item>
<item>com.android.systemui.globalactions.GlobalActionsComponent</item>//关机菜单
<item>com.android.systemui.ScreenDecorations</item>
<item>com.android.systemui.biometrics.BiometricDialogImpl</item> //生物识别(指纹解锁,人脸识别等)
<item>com.android.systemui.SliceBroadcastRelayHandler</item>
<item>com.android.systemui.SizeCompatModeActivityController</item>
<item>com.android.systemui.statusbar.notification.InstantAppNotifier</item> //通知
<item>com.android.systemui.theme.ThemeOverlayController</item>
</string-array>
二.状态栏SystemBars
查看SystemBars的start方法,调用了createStatusBarFromConfig,创建了StatusBar对象
private void createStatusBarFromConfig() {
if (DEBUG) Log.d(TAG, "createStatusBarFromConfig");
final String clsName = mContext.getString(R.string.config_statusBarComponent); //frameworks/base/packages/SystemUI/res/values/config.xml,值为com.android.systemui.statusbar.phone.StatusBar
.....
mStatusBar = (SystemUI) cls.newInstance();
...,..
mStatusBar.mContext = mContext;
mStatusBar.mComponents = mComponents;
if (mStatusBar instanceof StatusBar) {
SystemUIFactory.getInstance().getRootComponent()
.getStatusBarInjector()
.createStatusBar((StatusBar) mStatusBar);
}
mStatusBar.start(); //启动
if (DEBUG) Log.d(TAG, "started " + mStatusBar.getClass().getSimpleName());
}
查看StatusBar的start方法,重点关注下面逻辑
mNetworkController = Dependency.get(NetworkController.class); //wifi或者数据图标相关,NetworkControllerImpl
mBatteryController = Dependency.get(BatteryController.class); //电池图标相关
createAndAddWindows(result); //创建view
// Lastly, call to the icon policy to install/update all the icons.
mIconPolicy = new PhoneStatusBarPolicy(mContext, mIconController);
mSignalPolicy = new StatusBarSignalPolicy(mContext, mIconController);
//createAndAddWindows
public void createAndAddWindows(@Nullable RegisterStatusBarResult result) {
makeStatusBarView(result);
...
}
protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
inflateStatusBarWindow(context); //R.layout.super_status_bar
FragmentHostManager.get(mStatusBarWindow) //顶部状态栏CollapsedStatusBarFragment
.addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> {
CollapsedStatusBarFragment statusBarFragment =
(CollapsedStatusBarFragment) fragment;
statusBarFragment.initNotificationIconArea(mNotificationIconAreaController);
}).getFragmentManager()
.beginTransaction()
.replace(R.id.status_bar_container, new CollapsedStatusBarFragment(),
CollapsedStatusBarFragment.TAG)
.commit();
createNavigationBar(result);//底部导航栏
}
1.状态栏图标的添加StatusBarIconController
参考https://blog.csdn.net/qq_30295213/article/details/102900483
添加的icon定义在/frameworks/base/core/res/res/values/config.xml中的config_statusBarIcons,总共32个
代码中添加的icon位于PhoneStatusBarPolicy.java中的构造方法
updateTTY(); //tty,电传打字机
updateBluetooth(); //bluetooth
mIconController.setIcon(mSlotAlarmClock, R.drawable.stat_sys_alarm, null); //alarm_clock,
mIconController.setIcon(mSlotZen, R.drawable.stat_sys_dnd, null); //zen
mIconController.setIcon(mSlotVolume, R.drawable.stat_sys_ringer_vibrate, null); //volume
mIconController.setIcon(mSlotCast, R.drawable.stat_sys_cast, null); //cast
updateHotspotIcon(); //hotspot
mIconController.setIcon(mSlotManagedProfile, R.drawable.stat_sys_managed_profile_status //managed_profile ,工作资料
mIconController.setIcon(mSlotDataSaver, R.drawable.stat_sys_data_saver //data_saver,省流模式
mIconController.setIcon(mSlotLocation, LOCATION_STATUS_ICON_ID, // 定位
mIconController.setIcon(mSlotSensorsOff, R.drawable.stat_sys_sensors_off //sensors_of 传感器关闭
2.网络相关图标的添加(NetworkController)
查看NetworkControllerImpl的构造方法
final SparseArray<MobileSignalController> mMobileSignalControllers = new SparseArray<>();
mDataUsageController = dataUsageController;
mWifiSignalController = new WifiSignalController(mContext, mHasMobileDataFeature,
mCallbackHandler, this, mWifiManager);
mEthernetSignalController = new EthernetSignalController(mContext, mCallbackHandler, this);
最后通过mReceiverHandler.post(mRegisterListeners);注册相关监听,查看registerListeners
mobileSignalController.registerListener();
mobileSignalController.registerFiveGStateListener(mFiveGServiceClient);
mContext.registerReceiver(this, filter, null, mReceiverHandler);
updateMobileControllers();
当收到来自ConnectivityService.java中的CONNECTIVITY_ACTION广播时
updateConnectivity
->pushConnectivityToSignals
//pushConnectivityToSignals
mobileSignalController.updateConnectivity(mConnectedTransports, mValidatedTransports);
mWifiSignalController.updateConnectivity(mConnectedTransports, mValidatedTransports);
mEthernetSignalController.updateConnectivity(mConnectedTransports, mValidatedTransports);
2.1数据网络图标更新 (status_bar_mobile)
mobileSignalController.updateConnectivity
-->notifyListenersIfNecessary
-->notifyListeners
-->notifyListeners(mCallbackHandler) //NetworkControllerImpl中的mCallbackHandler
//notifyListeners主要逻辑如下
//图标状态,重点关注,用于判断显示什么样的图标(叉号,感叹号等),可定制显示图标
IconState statusIcon = new IconState(mCurrentState.enabled && !mCurrentState.airplaneMode,getCurrentIconId(), contentDescription);
qsIcon = new IconState(mCurrentState.enabled && !mCurrentState.isEmergency, getQsCurrentIconId(), contentDescription);
//下行
boolean activityIn = mCurrentState.dataConnected&& !mCurrentState.carrierNetworkChangeMode&& mCurrentState.activityIn;
//上行
boolean activityOut = mCurrentState.dataConnected&& !mCurrentState.carrierNetworkChangeMode && mCurrentState.activityOut;
//类型(LTE,NR)
int typeIcon = (showDataIcon || mConfig.alwaysShowDataRatIcon|| mConfig.alwaysShowNetworkTypeIcon) ? icons.mDataType : 0;
//Volte
int volteIcon = mConfig.showVolteIcon && isVolteSwitchOn() ? getVolteResId() : 0;
callback. setMobileDataIndicators(statusIcon, qsIcon, typeIcon, qsTypeIcon,
activityIn, activityOut,volteIcon,
dataContentDescription, description, icons.mIsWide,
mSubscriptionInfo.getSubscriptionId(), mCurrentState.roaming); //callback为StatusBarSignalPolicy.java
其中mCurrentState是通过updateTelephony进行更新,mCurrentState的相关参数如下
// mCurrentState.enabled ,在构造方法中赋值
mCurrentState.enabled = hasMobileData //为mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
//mCurrentState.isEmergency, 在updateTelephony中赋值
mCurrentState.isEmergency = isEmergencyOnly(); //调用mServiceState.isEmergencyOnly(),mServiceState来自onServiceStateChanged
//mCurrentState.airplaneMode,在NetworkControllerImpl中的updateAirplaneMode赋值
boolean airplaneMode = (Settings.Global.getInt(mContext.getContentResolver(),Settings.Global.AIRPLANE_MODE_ON, 0) == 1);
//mCurrentState.connected,在updateTelephony中赋值
mCurrentState.connected = Utils.isInService(mServiceState)
//mCurrentState.dataConnected,在updateTelephony中赋值
mCurrentState.dataConnected = mCurrentState.connected && (mDataState == TelephonyManager.DATA_CONNECTED || mMMSDataState == DataState.CONNECTED);
//mCurrentState.carrierNetworkChangeMode,在NetworkControllerImpl.java中初始化
String carrierNetworkChange = args.getString("carriernetworkchange")
boolean show = carrierNetworkChange.equals("show");
controller.setCarrierNetworkChangeMode(show);
//mCurrentState.activityIn,mCurrentState.activityOut来自onDataActivity传进的参数
//mCurrentState.iconGroup //重点关注,决定传进的参数typeIcon
分析mCurrentState.iconGroup
//初始值,构造方法中
mCurrentState.iconGroup = mDefaultIcons // mDefaultIcons 来自mapIconSets
//mapIconSets
!mConfig.showAtLeast3G 来判断是TelephonyIcons.G还是TelephonyIcons.THREE_G
//mConfig为创建NetworkControllerImpl传进的参数
//在updateTelephony中会根据注网状态来显示什么图标
分析getCurrentIconId(获取显示Icon的ID,决定显示哪个图标)
public int getCurrentIconId() {
if (mCurrentState.iconGroup == TelephonyIcons.CARRIER_NETWORK_CHANGE) {//运营商网络正在更新
return SignalDrawable.getCarrierChangeState(getNumLevels());
} else if (mCurrentState.connected) { //已联网
int level = mCurrentState.level;
if (mInflateSignalStrengths) {
level++;
}
boolean dataDisabled = mCurrentState.userSetup
&& (mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED
|| mCurrentState.iconGroup == TelephonyIcons.NOT_DEFAULT_DATA);
boolean noInternet = mCurrentState.inetCondition == 0;
boolean cutOut = dataDisabled || noInternet;
if (mConfig.hideNoInternetState) {
cutOut = false;
}
return SignalDrawable.getState(level, getNumLevels(), cutOut); //cutOut为是否显示X号
} else if (mCurrentState.enabled) { //有插卡未联网
return SignalDrawable.getEmptyState(getNumLevels());
} else {
return 0;
}
}
继续看callback. setMobileDataIndicators,实际调用的是StatusBarSignalPolicy的方法,其逻辑如下
public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType,
int qsType, boolean activityIn, boolean activityOut, int volteIcon,
String typeContentDescription, String description, boolean isWide,
int subId, boolean roaming) {
MobileIconState state = getState(subId);
boolean typeChanged = statusType != state.typeId && (statusType == 0 || state.typeId == 0);//传进的statusType发生改变
state.XXX=XXX; //保存传进的参数
//mSlotMobile为mobile
mIconController.setMobileIcons(mSlotMobile, MobileIconState.copyStates(mMobileStates));//更新数据图标,重点关注
if (typeChanged) {
updateWifiIconWithState(wifiCopy); //更新wifi图标
}
}
}
//先看wifi图标,mIconController为StatusBarIconControllerImpl.java
private void updateWifiIconWithState(WifiIconState state) {
if (state.visible && state.resId > 0) {
mIconController.setSignalIcon(mSlotWifi, state);
mIconController.setIconVisibility(mSlotWifi, true);
} else {
mIconController.setIconVisibility(mSlotWifi, false);
}
}
//设置数据图标
public void setMobileIcons(String slot, List<MobileIconState> iconStates) {
Slot mobileSlot = getSlot(slot);
int slotIndex = getSlotIndex(slot);
Collections.reverse(iconStates);
for (MobileIconState state : iconStates) {
StatusBarIconHolder holder = mobileSlot.getHolderForTag(state.subId);
if (holder == null) {
holdseer = StatusBarIconHolder.fromMobileIconState(state);
setIcon(slotIndex, holder);//重点关注
} else {
holder.setMobileState(state); //设置
handleSet(slotIndex, holder);
}
}
}
//setIcon最终调用到StatusBarIconController中的子类TintedIconManager(或者DarkIconManager)中的onIconAdded
//CollapsedStatusBarFragment.java(顶部状态栏)传进的是DarkIconManager,KeyguardStatusBarView.java(锁屏)和QuickStatusBarHeader.java(下拉)传进的是TintedIconManager
//均调用到addHolder
protected StatusIconDisplayable addHolder(int index, String slot, boolean blocked,
StatusBarIconHolder holder) {
switch (holder.getType()) {
case TYPE_ICON:
return addIcon(index, slot, blocked, holder.getIcon());//图标
case TYPE_WIFI:
return addSignalIcon(index, slot, holder.getWifiState());
case TYPE_MOBILE:
return addMobileIcon(index, slot, holder.getMobileState());//数据图标
}
return null;
}
2.2 wifi图标
通过setWifiIndicators进行设置,来自WifiSignalController.java中的notifyListeners,其主要逻辑如下
public void notifyListeners(SignalCallback callback) {
// only show wifi in the cluster if connected or if wifi-only
boolean wifiVisible = mCurrentState.enabled
&& (mCurrentState.connected || !mHasMobileData);//wifi是否可见
String wifiDesc = wifiVisible ? mCurrentState.ssid : null;
boolean ssidPresent = wifiVisible && mCurrentState.ssid != null;
String contentDescription = getStringIfExists(getContentDescription());
if (mCurrentState.inetCondition == 0) {
contentDescription += ("," + mContext.getString(R.string.data_connection_no_internet));
}
IconState statusIcon = new IconState(wifiVisible, getCurrentIconId(), contentDescription);//依旧关注getCurrentIconId
IconState qsIcon = new IconState(mCurrentState.connected, getQsCurrentIconId(),
contentDescription);
callback.setWifiIndicators(mCurrentState.enabled, statusIcon, qsIcon,
ssidPresent && mCurrentState.activityIn, ssidPresent && mCurrentState.activityOut,
wifiDesc, mCurrentState.isTransient, mCurrentState.statusLabel);
}
public int getCurrentIconId() {
if (mCurrentState.connected) {
return getIcons().mSbIcons[mCurrentState.inetCondition][mCurrentState.level];
} else if (mCurrentState.enabled) {
return getIcons().mSbDiscState;
} else {
return getIcons().mSbNullState;
}
}
2.3以太网图标(status_bar_ethernet)
通过setEthernetIndicators进行设置,来自EthernetSignalController.java中的otifyListeners
2.4飞行模式(status_bar_airplane)
通过setIsAirplaneMode设置,来自NetworkControllerImpl.java中的notifyListeners()
2.5电池(status_bar_battery)
参考https://blog.csdn.net/xiaowang_lj/article/details/126763309