9.0 SystemUI 状态栏 系统状态图标初始化流程

 

 

 

 

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()方法进行注册。

BatteryMeterView.java 电池图标  

Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mBattery);

Clock.java  时间图标

    Dependency.get(DarkIconDispatcher.class).addDarkReceiver(this);

 

本篇到此就算结束了

 

 

 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值