statusIcons 代表系统状态图标 例如耳机、蓝牙、位置信息、网络等等,具体定义在config_statusBarIcons中。
在StatusBarIconControllerImpl.java的构造函数中被用来初始化StatusBarIconList.java中的
private ArrayList<Slot> mSlots = new ArrayList<>();
以后添加跟更新图标说所的slot跟index就是根据这个顺序来对应排序的
比如slot =headset index =3;
一:其布局文件
system_icons.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/system_icons"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical">
<com.android.systemui.statusbar.phone.StatusIconContainer android:id="@+id/statusIcons"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:paddingEnd="@dimen/signal_cluster_battery_padding"
android:gravity="center_vertical"
android:orientation="horizontal"/>
<com.android.systemui.BatteryMeterView android:id="@+id/battery"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:clipToPadding="false"
android:clipChildren="false" />
</LinearLayout>
我们的system_icons.xml被include在status_bar.xml中,在CollapsedStatusBarFragment.java中被一同初始化。
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.status_bar, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mDarkIconManager = new DarkIconManager(view.findViewById(R.id.statusIcons));
android.util.Log.d("lgy_debug_systemui","CollapsedStatusBarFragment.java addIconGroup");
Dependency.get(StatusBarIconController.class).addIconGroup(mDarkIconManager);
}
初始化状态图标:
以我自己添加的Log作为主线思路。
statusBar.java start()..PhoneStatusBarPolicy .//在statusBar.java的start方法中初始化PhoneStatusBarPolicy
PhoneStatusBarPolicy.java--->PhoneStatusBarPolicy() .//PhoneStatusBarPolicy的构造方法
StatusBarIconControllerImpl.java setIconVisibility slot =tty// updateTTY();
StatusBarIconControllerImpl.java setIconVisibility visibility =false// updateTTY();
PhoneStatusBarPolicy.java--->updateBluetooth() .//
StatusBarIconControllerImpl.java setIcon slot = bluetooth
StatusBarIconControllerImpl.java setIcon resourceId = 2131231688
StatusBarIconControllerImpl.java setIcon holder = null
StatusBarIconControllerImpl.java 5555 setIcon index =15
StatusBarIconControllerImpl.java 5555 setIcon isNew =true
StatusBarIconControllerImpl.java addSystemIcon
StatusBarIconControllerImpl.java addSystemIcon mIconGroups.size =0//mIconGroups size为0,不会跑onIconAdded
StatusBarIconControllerImpl.java setIconVisibility slot =bluetooth
StatusBarIconControllerImpl.java setIconVisibility visibility =false
KeyguardstatusBarView.java--->onAttachedToWindow begin addIconGroup//在KeyguardstatusBarView
StatusBarIconControllerImpl.java addIconGroup mIconGroups.size() =1
StatusBarIconControllerImpl.java addIconGroup allSlots.size() =30
StatusBarIconControllerImpl.java addIconGroup begion IconAdded
StatusBarIconController.java--->onIconAdded 222
StatusBarIconController.java--->addHolder addHolder.getType = 0
StatusBarIconController.java--->addHolder slot = bluetooth
tatusBarIconController.java--->addIcon 2222 //TintedIconManager.onIconAdded()
CollapsedStatusBarFragment.java addIconGroup
StatusBarIconControllerImpl.java addIconGroup mIconGroups.size() =2
StatusBarIconControllerImpl.java addIconGroup allSlots.size() =30
StatusBarIconControllerImpl.java addIconGroup begion IconAdded
StatusBarIconController.java--->onIconAdded 3333 //DarkIconManager.onIconAdded()
StatusBarIconController.java--->addHolder addHolder.getType = 0
StatusBarIconController.java--->addHolder slot = bluetooth
StatusBarIconController.java--->addIcon 2222
DarkIconDispatherImpl.java addDarkReceiver
QuickStatusBarHeader.java--->onAttachedToWindow begin addIconGroup
StatusBarIconControllerImpl.java addIconGroup mIconGroups.size() =3
StatusBarIconControllerImpl.java addIconGroup allSlots.size() =30
StatusBarIconControllerImpl.java addIconGroup begion IconAdded
StatusBarIconController.java--->onIconAdded 222 //TintedIconManager.onIconAdded()
StatusBarIconController.java--->addHolder addHolder.getType = 0
StatusBarIconController.java--->addHolder slot = bluetooth
StatusBarIconController.java--->addIcon 2222
1 StatusBar.java 初始化PhoneStatusBarPolicy
@Override
public void start() {
mIconPolicy = new PhoneStatusBarPolicy(mContext, mIconController);
}
protected void makeStatusBarView() {
mIconController = Dependency.get(StatusBarIconController.class);
}
那么来看下PhoneStatusBarPolicy的构造函数
public PhoneStatusBarPolicy(Context context, StatusBarIconController iconController) {
mContext = context;
mIconController = iconController;
mCast = Dependency.get(CastController.class);
mHotspot = Dependency.get(HotspotController.class);
mBluetooth = Dependency.get(BluetoothController.class);
mNextAlarmController = Dependency.get(NextAlarmController.class);
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
mUserInfoController = Dependency.get(UserInfoController.class);
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
mRotationLockController = Dependency.get(RotationLockController.class);
mDataSaver = Dependency.get(DataSaverController.class);
mZenController = Dependency.get(ZenModeController.class);
mProvisionedController = Dependency.get(DeviceProvisionedController.class);
mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
mLocationController = Dependency.get(LocationController.class);
mSlotCast = context.getString(com.android.internal.R.string.status_bar_cast);
mSlotHotspot = context.getString(com.android.internal.R.string.status_bar_hotspot);
mSlotBluetooth = context.getString(com.android.internal.R.string.status_bar_bluetooth);
mSlotTty = context.getString(com.android.internal.R.string.status_bar_tty);
mSlotZen = context.getString(com.android.internal.R.string.status_bar_zen);
mSlotVolume = context.getString(com.android.internal.R.string.status_bar_volume);
mSlotAlarmClock = context.getString(com.android.internal.R.string.status_bar_alarm_clock);
mSlotManagedProfile = context.getString(
com.android.internal.R.string.status_bar_managed_profile);
mSlotRotate = context.getString(com.android.internal.R.string.status_bar_rotate);
mSlotHeadset = context.getString(com.android.internal.R.string.status_bar_headset);
mSlotDataSaver = context.getString(com.android.internal.R.string.status_bar_data_saver);
mSlotLocation = context.getString(com.android.internal.R.string.status_bar_location);
// M: ignor for BSP+
// mSlotEmbms = context.getString(com.android.internal.R.string.status_bar_embms);
mSlotEmbms = "embms";
// listen for broadcasts
IntentFilter filter = new IntentFilter();
/// M: [Multi-User] Will register this action using special receiver.
//filter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
filter.addAction(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
filter.addAction(AudioManager.ACTION_HEADSET_PLUG);
filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
filter.addAction(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED);
filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
/// M: [Multi-User] Add user switched action for updating possible alarm icon.
filter.addAction(Intent.ACTION_USER_SWITCHED);
filter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED);
/// M: Add icon for embms session.
filter.addAction(TelephonyIntents.ACTION_EMBMS_SESSION_STATUS_CHANGED);
mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
/// M: [Multi-User] Register Alarm intent by user
registerAlarmClockChanged(UserHandle.USER_OWNER, false);
// listen for user / profile change.
try {
ActivityManager.getService().registerUserSwitchObserver(mUserSwitchListener, TAG);
} catch (RemoteException e) {
// Ignore
}
android.util.Log.d("lgy_debug_systemui","PhoneStatusBarPolicy.java--->PhoneStatusBarPolicy() .");
// TTY status
updateTTY();
// bluetooth status
updateBluetooth();
//eMBMS status
mIconController.setIcon(mSlotEmbms, R.drawable.stat_sys_embms, null);
mIconController.setIconVisibility(mSlotEmbms, false);
// Alarm clock
mIconController.setIcon(mSlotAlarmClock, R.drawable.stat_sys_alarm, null);
mIconController.setIconVisibility(mSlotAlarmClock, false);
// zen
mIconController.setIcon(mSlotZen, R.drawable.stat_sys_zen_important, null);
mIconController.setIconVisibility(mSlotZen, false);
// volume
mIconController.setIcon(mSlotVolume, R.drawable.stat_sys_ringer_vibrate, null);
mIconController.setIconVisibility(mSlotVolume, false);
updateVolumeZen();
// cast
mIconController.setIcon(mSlotCast, R.drawable.stat_sys_cast, null);
mIconController.setIconVisibility(mSlotCast, false);
// hotspot
mIconController.setIcon(mSlotHotspot, R.drawable.stat_sys_hotspot,
mContext.getString(R.string.accessibility_status_bar_hotspot));
mIconController.setIconVisibility(mSlotHotspot, mHotspot.isHotspotEnabled());
// managed profile
mIconController.setIcon(mSlotManagedProfile, R.drawable.stat_sys_managed_profile_status,
mContext.getString(R.string.accessibility_managed_profile));
mIconController.setIconVisibility(mSlotManagedProfile, mManagedProfileIconVisible);
// data saver
mIconController.setIcon(mSlotDataSaver, R.drawable.stat_sys_data_saver,
context.getString(R.string.accessibility_data_saver_on));
mIconController.setIconVisibility(mSlotDataSaver, false);
mRotationLockController.addCallback(this);
mBluetooth.addCallback(this);
mProvisionedController.addCallback(this);
mZenController.addCallback(this);
mCast.addCallback(mCastCallback);
mHotspot.addCallback(mHotspotCallback);
mNextAlarmController.addCallback(mNextAlarmCallback);
mDataSaver.addCallback(this);
mKeyguardMonitor.addCallback(this);
mLocationController.addCallback(this);
SysUiServiceProvider.getComponent(mContext, CommandQueue.class).addCallbacks(this);
ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskListener);
// Clear out all old notifications on startup (only present in the case where sysui dies)
NotificationManager noMan = mContext.getSystemService(NotificationManager.class);
for (StatusBarNotification notification : noMan.getActiveNotifications()) {
if (notification.getId() == SystemMessage.NOTE_INSTANT_APPS) {
noMan.cancel(notification.getTag(), notification.getId());
}
}
DockedStackExistsListener.register(exists -> {
mDockedStackExists = exists;
updateForegroundInstantApps();
});
}
不难看出,在构造器里面主要干了以下几件事:
1,初始化各个Slot的名字以及其控制类接口.
以Slot为bluetooth为例
mBluetooth = Dependency.get(BluetoothController.class);
mSlotBluetooth = context.getString(com.android.internal.R.string.status_bar_bluetooth);
public interface BluetoothController extends CallbackController<Callback>, Dumpable {
boolean isBluetoothSupported();
boolean isBluetoothEnabled();
int getBluetoothState();
boolean isBluetoothConnected();
boolean isBluetoothConnecting();
String getConnectedDeviceName();
void setBluetoothEnabled(boolean enabled);
Collection<CachedBluetoothDevice> getDevices();
void connect(CachedBluetoothDevice device);
void disconnect(CachedBluetoothDevice device);
boolean canConfigBluetooth();
int getMaxConnectionState(CachedBluetoothDevice device);
int getBondState(CachedBluetoothDevice device);
List<CachedBluetoothDevice> getConnectedDevices();
public interface Callback {
void onBluetoothStateChange(boolean enabled);
void onBluetoothDevicesChanged();
}
}
BluetoothController 的最终实现者是BluetoothControllerImpl,聪明的小伙伴应该从接口名字就能看出来,这个类就是对我们蓝牙状态的管控类了。
2,注册想要监听的广播,如ACTION_HEADSET_PLUG、ACTION_SIM_STATE_CHANGED、ACTION_USER_SWITCHED
filter.addAction(AudioManager.ACTION_HEADSET_PLUG);
filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
注册这些感兴趣的广播action,主要是通过其状态来更新其对应在对应状态栏上的显示状态。来看mIntentReceiver;
/*private*/ BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
switch (action) {
case AudioManager.RINGER_MODE_CHANGED_ACTION:
case AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION:
updateVolumeZen();
break;
case TelephonyIntents.ACTION_SIM_STATE_CHANGED:
// Avoid rebroadcast because SysUI is direct boot aware.
if (intent.getBooleanExtra(TelephonyIntents.EXTRA_REBROADCAST_ON_UNLOCK,
false)) {
break;
}
updateSimState(intent);
break;
case TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED:
updateTTY(intent.getIntExtra(TelecomManager.EXTRA_CURRENT_TTY_MODE,
TelecomManager.TTY_MODE_OFF));
break;
case Intent.ACTION_MANAGED_PROFILE_AVAILABLE:
case Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE:
case Intent.ACTION_MANAGED_PROFILE_REMOVED:
updateManagedProfile();
break;
case AudioManager.ACTION_HEADSET_PLUG:
updateHeadsetPlug(intent);
break;
/// M: [Multi-User] Register Alarm intent by user @{
case Intent.ACTION_USER_SWITCHED:
updateAlarm();
int newUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
registerAlarmClockChanged(newUserId, true);
break;
/// M: @}
/// M: embms session status intent @{
case TelephonyIntents.ACTION_EMBMS_SESSION_STATUS_CHANGED:
updateEmbmsState(intent);
break;
/// M: @}
}
}
};
3,开始初始化各个Slot的图标以及显示状态
updateTTY();
// bluetooth status
updateBluetooth();
//eMBMS status
mIconController.setIcon(mSlotEmbms, R.drawable.stat_sys_embms, null);
mIconController.setIconVisibility(mSlotEmbms, false);
// hotspot
mIconController.setIcon(mSlotHotspot, R.drawable.stat_sys_hotspot,
mContext.getString(R.string.accessibility_status_bar_hotspot));
mIconController.setIconVisibility(mSlotHotspot, mHotspot.isHotspotEnabled());
来看bluetootch 是如何更新其状态图标的
private final void updateBluetooth() {
android.util.Log.d("lgy_debug_systemui","PhoneStatusBarPolicy.java--->updateBluetooth() .");
int iconId = R.drawable.stat_sys_data_bluetooth;//显示蓝牙图标资源
String contentDescription =
mContext.getString(R.string.accessibility_quick_settings_bluetooth_on);
boolean bluetoothVisible = false;
if (mBluetooth != null) {
if (mBluetooth.isBluetoothConnected()) {//蓝牙开关是否打开
iconId = R.drawable.stat_sys_data_bluetooth_connected;
contentDescription = mContext.getString(R.string.accessibility_bluetooth_connected);
bluetoothVisible = mBluetooth.isBluetoothEnabled();//
}
}
mIconController.setIcon(mSlotBluetooth, iconId, contentDescription);//设置蓝牙图标
mIconController.setIconVisibility(mSlotBluetooth, bluetoothVisible);//蓝牙图标与否显示在状态栏上否
}
最后都是调用mIconController 来设置图标资源与控制是否在状态栏上显示的;
mIconController.setIcon(mSlotBluetooth, iconId, contentDescription);//设置蓝牙图标
mIconController.setIconVisibility(mSlotBluetooth, bluetoothVisible);//蓝牙图标与否显示在状态栏上
mIconController 是StatusBarIconController,它是一个interface,其实现者是StatusBarIconControllerImpl;
StatusBarIconControllerImpl.java
@Override
public void setIcon(String slot, int resourceId, CharSequence contentDescription) {
int index = getSlotIndex(slot);
StatusBarIconHolder holder = getIcon(index, 0);
android.util.Log.d("lgy_debug_systemui","StatusBarIconControllerImpl.java setIcon slot = "+slot);
android.util.Log.d("lgy_debug_systemui","StatusBarIconControllerImpl.java setIcon resourceId = "+resourceId);
android.util.Log.d("lgy_debug_systemui","StatusBarIconControllerImpl.java setIcon holder = "+holder);
if (holder == null) {
StatusBarIcon icon = new StatusBarIcon(UserHandle.SYSTEM, mContext.getPackageName(),
Icon.createWithResource(
mContext, resourceId), 0, 0, contentDescription);
holder = StatusBarIconHolder.fromIcon(icon);
setIcon(index, holder);
} else {
holder.getIcon().icon = Icon.createWithResource(mContext, resourceId);
holder.getIcon().contentDescription = contentDescription;
handleSet(index, holder);
}
}
D lgy_debug_systemui: StatusBarIconControllerImpl.java setIcon holder = null
首先获取holder,然后判断其是否为null,第一次开机holder 为null,所以都会走setIcon(index, holder);
@Override
public void setIcon(int index, @NonNull StatusBarIconHolder holder) {
boolean isNew = getIcon(index, holder.getTag()) == null;
android.util.Log.d("lgy_debug_systemui","StatusBarIconControllerImpl.java 5555 setIcon index ="+index);
android.util.Log.d("lgy_debug_systemui","StatusBarIconControllerImpl.java 5555 setIcon isNew="+isNew);
super.setIcon(index, holder);
if (isNew) {
addSystemIcon(index, holder);
} else {
handleSet(index, holder);
}
}
D lgy_debug_systemui: StatusBarIconControllerImpl.java 5555 setIcon isNew =true
判断是不是新要加的,isNew为true,走 addSystemIcon(index, holder);
private void addSystemIcon(int index, StatusBarIconHolder holder) {
android.util.Log.d("lgy_debug_systemui","StatusBarIconControllerImpl.java addSystemIcon ");
String slot = getSlotName(index);
int viewIndex = getViewIndex(index, holder.getTag());
boolean blocked = mIconBlacklist.contains(slot);
android.util.Log.d("lgy_debug_systemui","StatusBarIconControllerImpl.java addSystemIcon mIconGroups.size ="+mIconGroups.size());
mIconLogger.onIconVisibility(getSlotName(index), holder.isVisible());
mIconGroups.forEach(l -> l.onIconAdded(viewIndex, slot, blocked, holder));
}
刚开始以为走到mIconGroups.forEach(l -> l.onIconAdded(viewIndex, slot, blocked, holder));就完了,已经把图标都初始化完了,其实不然。为什么呢?因为开机初始化的时候mIconGroups的size现在还是0哦。
D lgy_debug_systemui: StatusBarIconControllerImpl.java addSystemIcon mIconGroups.size =0
所以到这里onIconAdded 这个方法还没执行呢。
那么问题来了,是在什么时候才执行onIconAdded的呢?其实是在addIconGroup这个方法中调用 group.onIconAdded真正的初始化icon;
SystemUI中有3个不同的地方调用到addIconGroup;
第一个是我们的锁屏UI
KeyguardstatusBarView.java--->onAttachedToWindow begin addIconGroup
D lgy_debug_systemui: StatusBarIconControllerImpl.java addIconGroup mIconGroups.size() =1
第二个是我们的状态栏UI
CollapsedStatusBarFragment.java---》onViewCreated begin addIconGroup
D lgy_debug_systemui: StatusBarIconControllerImpl.java addIconGroup mIconGroups.size() =2
第三个是我们的下拉快捷图标QS
QuickStatusBarHeader.java--->onAttachedToWindow begin addIconGroup
D lgy_debug_systemui: StatusBarIconControllerImpl.java addIconGroup mIconGroups.size() =3
@Override
public void addIconGroup(IconManager group) {
mIconGroups.add(group);
android.util.Log.d("lgy_debug_systemui","StatusBarIconControllerImpl.java addIconGroup mIconGroups.size() ="+mIconGroups.size());
List<Slot> allSlots = getSlots();
android.util.Log.d("lgy_debug_systemui","StatusBarIconControllerImpl.java addIconGroup allSlots.size() ="+allSlots.size());
for (int i = 0; i < allSlots.size(); i++) {
Slot slot = allSlots.get(i);
List<StatusBarIconHolder> holders = slot.getHolderListInViewOrder();
boolean blocked = mIconBlacklist.contains(slot.getName());
for (StatusBarIconHolder holder : holders) {
int tag = holder.getTag();
int viewIndex = getViewIndex(getSlotIndex(slot.getName()), holder.getTag());
android.util.Log.d("lgy_debug_systemui","StatusBarIconControllerImpl.java addIconGroup begion IconAdded ");
group.onIconAdded(viewIndex, slot.getName(), blocked, holder);
}
}
}
@Override
protected void onIconAdded(int index, String slot, boolean blocked,
StatusBarIconHolder holder) {
android.util.Log.d("lgy_debug_systemui","StatusBarIconController.java--->onIconAdded 222");
StatusIconDisplayable view = addHolder(index, slot, blocked, holder);
view.setStaticDrawableColor(mColor);
view.setDecorColor(mColor);
}
protected StatusIconDisplayable addHolder(int index, String slot, boolean blocked,
StatusBarIconHolder holder) {
android.util.Log.d("lgy_debug_systemui","StatusBarIconController.java--->addHolder addHolder.getType = "+holder.getType());
android.util.Log.d("lgy_debug_systemui","StatusBarIconController.java--->addHolder slot = "+slot);
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;
}
根据holder的类型,走相对应的设置流程,蓝牙的类型为TYPE_ICON。走 addIcon(index, slot, blocked, holder.getIcon());
D lgy_debug_systemui: StatusBarIconController.java--->addHolder.getType = 0
protected StatusBarIconView addIcon(int index, String slot, boolean blocked,
StatusBarIcon icon) {
android.util.Log.d("lgy_debug_systemui","StatusBarIconController.java--->addIcon 2222");
StatusBarIconView view = onCreateStatusBarIconView(slot, blocked);
view.set(icon);
mGroup.addView(view, index, onCreateLayoutParams());//这里的mGroup就是在CollapsedStatusBarFragment.java初始化DarkIconManager时传下去的R.id.statusIcons我们的状态栏容器StatusIconContainer
return view;
}
这个StatusIconContainer实现的比较简单 感兴趣的朋友,自行去看看源码。
至此 mIconController.setIcon才算初始化完成了。
后面状态图标的更新流程会走以下流程,以headset为例
PhoneStatusBarPolicy.java--->updateHeadsetPlug() .
StatusBarIconControllerImpl.java setIcon slot = headset
StatusBarIconControllerImpl.java setIcon resourceId = 2131231117
StatusBarIconControllerImpl.java setIcon holder = com.android.systemui.statusbar.phone.StatusBarIconHolder@44079a0
handleSet(index, holder);
private void handleSet(int index, StatusBarIconHolder holder) {
int viewIndex = getViewIndex(index, holder.getTag());
mIconLogger.onIconVisibility(getSlotName(index), holder.isVisible());
mIconGroups.forEach(l -> l.onSetIconHolder(viewIndex, holder));
}
public void onSetIconHolder(int viewIndex, StatusBarIconHolder holder) {
android.util.Log.d("lgy_debug_systemui","StatusBarIconController.java--->onSetIconHolder 2 holder.getType() ="+holder.getType());
switch (holder.getType()) {
case TYPE_ICON:
onSetIcon(viewIndex, holder.getIcon());
return;
case TYPE_WIFI:
onSetSignalIcon(viewIndex, holder.getWifiState());
return;
case TYPE_MOBILE:
onSetMobileIcon(viewIndex, holder.getMobileState());
default:
break;
}
}
@Override
public void onSetIcon(int viewIndex, StatusBarIcon icon) {
android.util.Log.d("lgy_debug_systemui","StatusBarIconController.java--->onSetIcon 1 ");
super.onSetIcon(viewIndex, icon);
mDarkIconDispatcher.applyDark((DarkReceiver) mGroup.getChildAt(viewIndex));
}
public void onSetIcon(int viewIndex, StatusBarIcon icon) {
android.util.Log.d("lgy_debug_systemui","StatusBarIconController.java--->onSetIcon 2");
StatusBarIconView view = (StatusBarIconView) mGroup.getChildAt(viewIndex);
view.set(icon);
}
从父容器mGrop中通过ViewIndex获取到StatusBarIconView 这里就是我们的Headset,然后给他设置icon;
最后调用mDarkIconDispatcher.applyDark((DarkReceiver) mGroup.getChildAt(viewIndex));//给Headset图标设置颜色随背景而改变的功能
这个DarkReceiver是一个接口,其实现者是DarkIconDispatcherImpl.java
public interface DarkIconDispatcher {
void addDarkReceiver(DarkReceiver receiver);
// Used to reapply darkness on an object, must have previously been added through
// addDarkReceiver.
void applyDark(DarkReceiver object);
}
public void addDarkReceiver(DarkReceiver receiver) {
mReceivers.put(receiver, receiver);
receiver.onDarkChanged(mTintArea, mDarkIntensity, mIconTint);
}
public void applyDark(DarkReceiver object) {
mReceivers.get(object).onDarkChanged(mTintArea, mDarkIntensity, mIconTint);
}
状态栏上的图标都可以自己实现自己的onDarkChanged方法,当背景改变时调用自己的onDarkChanged;
Systemui中有一些自定义的view已经自己实现了onDarkChanged方法并通过addDarkReceiver()方法进行注册。
Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mBattery);
Clock.java 时间图标
Dependency.get(DarkIconDispatcher.class).addDarkReceiver(this);
本篇到此就算结束了