主要由四部分组成,
1.SigalClusterView (电池 基站信号)
2.notification_icon_area(消息推送图标区)
3.status_icons 包括静音icon 蓝牙icon 等共9个左右
4.下拉之后的view
SystemUI 第一次启动堆栈:
D/yzy (13114): com.android.systemui.statusbar.phone.PhoneStatusBar.addIcon(...)//添加状态icon
D/yzy (13114): com.android.systemui.statusbar.BaseStatusBar.start(...)
D/yzy (13114): com.android.systemui.statusbar.phone.PhoneStatusBar.bindViews(...)
D/yzy (13114): com.android.systemui.statusbar.phone.PhoneStatusBar.start(...)
D/yzy (13114): com.android.systemui.SystemUIService.onCreate(...)
D/yzy (13114): android.app.ActivityThread.handleCreateService(...)
D/yzy (13114): android.app.ActivityThread.access$1600(...)
D/yzy (13114): android.app.ActivityThread$H.handleMessage(...)
D/yzy (13114): android.os.Handler.dispatchMessage(...)
D/yzy (13114): android.os.Looper.loop(...)
D/yzy (13114): android.app.ActivityThread.main(...)
D/yzy (13114): java.lang.reflect.Method.invokeNative(...)
D/yzy (13114): java.lang.reflect.Method.invoke(...)
D/yzy (13114): com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(...)
D/yzy (13114): com.android.internal.os.ZygoteInit.main(...)
D/yzy (13114): dalvik.system.NativeStart.main(...)
BaseStatusBar.start(...):
// Connect in to the status bar manager service StatusBarIconList iconList = new StatusBarIconList(); ArrayList<IBinder> notificationKeys = new ArrayList<IBinder>(); ArrayList<StatusBarNotification> notifications = new ArrayList<StatusBarNotification>(); mCommandQueue.registerCallbacks(this, iconList); int[] switches = new int[7]; ArrayList<IBinder> binders = new ArrayList<IBinder>(); try { mBarService.registerStatusBar(mCommandQueue, iconList, notificationKeys, notifications, switches, binders); } catch (RemoteException ex) { // If the system process isn't there we're doomed anyway. }
当插入耳机的时候PhoneStatusBarPolicy updateHeadset
mService 是 StatusBarManagerService 的客户端
mService.setIcon("headset", icon, 0, null); mService.setIconVisibility("headset", plug);
通过AIDL 调用了StatusBarManagerService的 setIcon ,可是为什么这样调用之后 icon就显示出来了呢?
OK ! 是CommandQueue登场了,它正是binder 的 客户端。
public void setIcon(String slot, String iconPackage, int iconId, int iconLevel, String contentDescription) { enforceStatusBar(); synchronized (mIcons) { int index = mIcons.getSlotIndex(slot); if (index < 0) { throw new SecurityException("invalid status bar icon slot: " + slot); } StatusBarIcon icon = new StatusBarIcon(iconPackage, UserHandle.OWNER, iconId, iconLevel, 0, contentDescription); //Slog.d(TAG, "setIcon slot=" + slot + " index=" + index + " icon=" + icon); mIcons.setIcon(index, icon); if (mBar != null) { try { mBar.setIcon(index, icon); } catch (RemoteException ex) { } } } }CommandQueue.java
public void setIcon(int index, StatusBarIcon icon) { synchronized (mList) { int what = MSG_ICON | index; mHandler.removeMessages(what); mHandler.obtainMessage(what, OP_SET_ICON, 0, icon.clone()).sendToTarget(); } }
那第三方应用发送的通知是如何显示到状态栏的呢?
第三方应用: NotificationManager.notify( Notification notification) --->NotificationManagerService.enqueueNotificationWithTag --->StatusBarManagerService.addNotification ---->IStatusBar.addNotification -->执行SystemUI中的CommandQueue extends IStatusBar.Stub extends IStatusBar addNotification( Notification notification)涉及到了 第三方应用 systemServer SystemUI 三个进程之间的binder通信,remoteViews.apply创建了实际的View
remoteView 实现进程间view的传递,如AppWidget Notification。