目录
接上一篇《SystemUI源码分析之PhoneStatusBar启动流程简单分析》,我们简单的了解了是怎么启动PhoneStatusBar的,同时也知道在PhoneStatusBar的start()方法中主要执行了如下几个步骤:
一、createAndAddWindows()
二、addNavigationBar()
四、startKeyguard()
本文主要就对这几个步骤进行一定流程的分析和简答的介绍。
一、createAndAddWindows()
在start()方法中,如下一句,调用的父类BaseStatusBar.start()方法
//1.调用父类BaseStatusBar.start(),这里做了一些参数的初始化
super.start(); // calls createAndAddWindows()
1.BaseStatusBar.start()
public void start() {
//初始化一些管理服务类,和注册监听事件等
mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
mDisplay = mWindowManager.getDefaultDisplay();
mDevicePolicyManager = (DevicePolicyManager)mContext.getSystemService(
Context.DEVICE_POLICY_SERVICE);
mNotificationColorUtil = NotificationColorUtil.getInstance(mContext);
mNotificationData = new NotificationData(this);
mAccessibilityManager = (AccessibilityManager)
mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
mDreamManager = IDreamManager.Stub.asInterface(
ServiceManager.checkService(DreamService.DREAM_SERVICE));
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mContext.getContentResolver().registerContentObserver(
Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED), true,
mSettingsObserver);
......
//调用createAndAddWindows(),但这个是抽象的方法,子类必须实现
createAndAddWindows();
//用户添加和更换等广播监听
......
}
由于BaseStatusBar中的createAndAddWindows()是抽象方法,子类(PhoneStatusBar)必须实现,因此调用的是PhoneStatusBar中createAndAddWindows()。
2.PhoneStatusBar.createAndAddWindows()
@Override
public void createAndAddWindows() {
addStatusBarWindow();
}
private void addStatusBarWindow() {
makeStatusBarView(); //这里主要是构造SystemUI中的View,比如顶部状态栏,底部导航栏,快捷键栏,消息通知栏等View
mStatusBarWindowManager = new StatusBarWindowManager(mContext);
mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());//添加到窗口
}
3. PhoneStatusBar.makeStatusBarView()
这里就是初始化View,代码很长很长,看看初始化了什么。
protected PhoneStatusBarView makeStatusBarView() {
final Context context = mContext;
//加载资源、更新尺寸和更新资源
Resources res = context.getResources();
updateDisplaySize(); // populates mDisplayMetrics
updateResources();
//顶部状态栏布局
mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
R.layout.super_status_bar, null);
mStatusBarWindow.setService(this);
//设置触摸事件监听
mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
checkUserAutohide(v, event);
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (mExpandedVisible) {
animateCollapsePanels();
}
}
return mStatusBarWindow.onTouchEvent(event);
}
});
//初始化statusbarview控件
mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
mStatusBarView.setBar(this);
//初始化PanelHolder
PanelHolder holder = (PanelHolder) mStatusBarWindow.findViewById(R.id.panel_holder);
mStatusBarView.setPanelHolder(holder);
//初始化NotificationPanelView
mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(
R.id.notification_panel);
mNotificationPanel.setStatusBar(this);
if (!ActivityManager.isHighEndGfx()) {
//设置背景颜色
mStatusBarWindow.setBackground(null);
mNotificationPanel.setBackground(new FastColorDrawable(context.getColor(
R.color.notification_panel_solid_background)));
}
//设置Notification通知样式,添加事件
mHeadsUpManager = new HeadsUpManager(context, mStatusBarWindow);
mHeadsUpManager.setBar(this);
mHeadsUpManager.addListener(this);
mHeadsUpManager.addListener(mNotificationPanel);
mNotificationPanel.setHeadsUpManager(mHeadsUpManager);
mNotificationData.setHeadsUpManager(mHeadsUpManager);
if (MULTIUSER_DEBUG) {
mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById(
R.id.header_debug_info);
mNotificationPanelDebugText.setVisibility(View.VISIBLE);
}
try {
//是否显示NavigationBar,如果 showNav为true,就显示。同时设置一些事件的监听
boolean showNav = mWindowManagerService.hasNavigationBar();
if (DEBUG) Log.v(TAG, "hasNavigationBar=" + showNav);
if (showNav) {
mNavigationBarView =
(NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
mNavigationBarView.setDisabledFlags(mDisabled1);
mNavigationBarView.setBar(this);
mNavigationBarView.setOnVerticalChangedListener(
new NavigationBarView.OnVerticalChangedListener() {
@Override
public void onVerticalChanged(boolean isVertical) {
if (mAssistManager != null) {
mAssistManager.onConfigurationChanged();
}
mNotificationPanel.setQsScrimEnabled(!isVertical);
}
});
mNavigationBarView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
checkUserAutohide(v, event);
return false;
}});
}
} catch (RemoteException ex) {
// no window manager? good luck with that
}
mAssistManager = new AssistManager(this, context);
// figure out which pixel-format to use for the status bar.
//状态栏使用的像素格式
mPixelFormat = PixelFormat.OPAQUE;
//status_bar_expanded布局的控件
mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById(
R.id.notification_stack_scroller);
mStackScroller.setLongPressListener(getNotificationLongClicker());
mStackScroller.setPhoneStatusBar(this);
mStackScroller.setGroupManager(mGroupManager);
mStackScroller.setHeadsUpManager(mHeadsUpManager);
mGroupManager.setOnGroupChangeListener(mStackScroller);
//引入NotificationOverflowContainer的布局
mKeyguardIconOverflowContainer =
(NotificationOverflowContainer) LayoutInflater.from(mContext).inflate(
R.layout.status_bar_notification_keyguard_overflow, mStackScroller, false);
mKeyguardIconOverflowContainer.setOnActivatedListener(this);
mKeyguardIconOverflowContainer.setOnClickListener(mOverflowClickListener);
mStackScroller.setOverflowContainer(mKeyguardIconOverflowContainer);
//引入SpeedBump的布局
SpeedBumpView speedBump = (SpeedBumpView) LayoutInflater.from(mContext).inflate(
R.layout.status_bar_notification_speed_bump, mStackScroller, false);
mStackScroller.setSpeedBumpView(speedBump);
//引入EmptyShadeView的布局
mEmptyShadeView = (EmptyShadeView) LayoutInflater.from(mContext).inflate(
R.layout.status_bar_no_notifications, mStackScroller, false);
mStackScroller.setEmptyShadeView(mEmptyShadeView);
//引入DismissView的布局
mDismissView = (DismissView) LayoutInflater.from(mContext).inflate(
R.layout.status_bar_notification_dismiss_all, mStackScroller, false);
mDismissView.setOnButtonClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MetricsLogger.action(mContext, MetricsLogger.ACTION_DISMISS_ALL_NOTES);
clearAllNotifications();
}
});
mStackScroller.setDismissView(mDismissView);
mExpandedContents = mStackScroller;
mBackdrop = (BackDropView) mStatusBarWindow.findViewById(R.id.backdrop);
mBackdropFront = (ImageView) mBackdrop.findViewById(R.id.backdrop_front);
mBackdropBack = (ImageView) mBackdrop.findViewById(R.id.backdrop_back);
ScrimView scrimBehind = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_behind);
ScrimView scrimInFront = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_in_front);
View headsUpScrim = mStatusBarWindow.findViewById(R.id.heads_up_scrim);
mScrimController = new ScrimController(scrimBehind, scrimInFront, headsUpScrim,
mScrimSrcModeEnabled);
mHeadsUpManager.addListener(mScrimController);
mStackScroller.setScrimController(mScrimController);
mScrimController.setBackDropView(mBackdrop);
mStatusBarView.setScrimController(mScrimController);
mDozeScrimController = new DozeScrimController(mScrimController, context);
mHeader = (StatusBarHeaderView) mStatusBarWindow.findViewById(R.id.header);
mHeader.setActivityStarter(this);
mKeyguardStatusBar = (KeyguardStatusBarView) mStatusBarWindow.findViewById(R.id.keyguard_header);
mKeyguardStatusView = mStatusBarWindow.findViewById(R.id.keyguard_status_view);
mKeyguardBottomArea =
(KeyguardBottomAreaView) mStatusBarWindow.findViewById(R.id.keyguard_bottom_area);
mKeyguardBottomArea.setActivityStarter(this);
mKeyguardBottomArea.setAssistManager(mAssistManager);
mKeyguardIndicationController = new KeyguardIndicationController(mContext,
(KeyguardIndicationTextView) mStatusBarWindow.findViewById(
R.id.keyguard_indication_text));
mKeyguardBottomArea.setKeyguardIndicationController(mKeyguardIndicationController);
// set the inital view visibility
setAreThereNotifications();
//创建IconController对象
mIconController = new StatusBarIconController(
mContext, mStatusBarView, mKeyguardStatusBar, this);
// Background thread for any controllers that need it.
//创建线程并启动线程
mHandlerThread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND);
mHandlerThread.start();
// Other icons
//位置
mLocationController = new LocationControllerImpl(mContext,
mHandlerThread.getLooper()); // will post a notification
//电池
mBatteryController = new BatteryController(mContext);
mBatteryController.addStateChangedCallback(new BatteryStateChangeCallback() {
@Override
public void onPowerSaveChanged() {
mHandler.post(mCheckBarModes);
if (mDozeServiceHost != null) {
mDozeServiceHost.firePowerSaveChanged(mBatteryController.isPowerSave());
}
}
@Override
public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
// noop
}
});
//网络
mNetworkController = new NetworkControllerImpl(mContext, mHandlerThread.getLooper());
mHotspotController = new HotspotControllerImpl(mContext);
//蓝牙
mBluetoothController = new BluetoothControllerImpl(mContext, mHandlerThread.getLooper());
//安全
mSecurityController = new SecurityControllerImpl(mContext);
if (mContext.getResources().getBoolean(R.bool.config_showRotationLock)) {
mRotationLockController = new RotationLockControllerImpl(mContext);
}
//用户信息
mUserInfoController = new UserInfoController(mContext);
//音量
mVolumeComponent = getComponent(VolumeComponent.class);
if (mVolumeComponent != null) {
mZenModeController = mVolumeComponent.getZenController();
}
//投射
mCastController = new CastControllerImpl(mContext);
//信号
final SignalClusterView signalCluster =
(SignalClusterView) mStatusBarView.findViewById(R.id.signal_cluster);
final SignalClusterView signalClusterKeyguard =
(SignalClusterView) mKeyguardStatusBar.findViewById(R.id.signal_cluster);
final SignalClusterView signalClusterQs =
(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);
final boolean isAPhone = mNetworkController.hasVoiceCallingFeature();
if (isAPhone) {
mNetworkController.addEmergencyListener(mHeader);
}
//手电筒
mFlashlightController = new FlashlightController(mContext);
mKeyguardBottomArea.setFlashlightController(mFlashlightController);
mKeyguardBottomArea.setPhoneStatusBar(this);
mKeyguardBottomArea.setUserSetupComplete(mUserSetup);
mAccessibilityController = new AccessibilityController(mContext);
mKeyguardBottomArea.setAccessibilityController(mAccessibilityController);
mNextAlarmController = new NextAlarmController(mContext);
//锁屏监听器
mKeyguardMonitor = new KeyguardMonitor(mContext);
if (UserSwitcherController.isUserSwitcherAvailable(UserManager.get(mContext))) {
mUserSwitcherController = new UserSwitcherController(mContext, mKeyguardMonitor,
mHandler);
}
//用户切换
mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext,
(ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_user_switcher),
mKeyguardStatusBar, mNotificationPanel, mUserSwitcherController);
// Set up the quick settings tile panel
mQSPanel = (QSPanel) mStatusBarWindow.findViewById(R.id.quick_settings_panel);
if (mQSPanel != null) {
final QSTileHost qsh = new QSTileHost(mContext, this,
mBluetoothController, mLocationController, mRotationLockController,
mNetworkController, mZenModeController, mHotspotController,
mCastController, mFlashlightController,
mUserSwitcherController, mKeyguardMonitor,
mSecurityController);
mQSPanel.setHost(qsh);
mQSPanel.setTiles(qsh.getTiles());
mBrightnessMirrorController = new BrightnessMirrorController(mStatusBarWindow);
mQSPanel.setBrightnessMirror(mBrightnessMirrorController);
mHeader.setQSPanel(mQSPanel);
qsh.setCallback(new QSTileHost.Callback() {
@Override
public void onTilesChanged() {
mQSPanel.setTiles(qsh.getTiles());
}
});
}
// User info. Trigger first load.
mHeader.setUserInfoController(mUserInfoController);
mKeyguardStatusBar.setUserInfoController(mUserInfoController);
mKeyguardStatusBar.setUserSwitcherController(mUserSwitcherController);
mUserInfoController.reloadUserInfo();
mHeader.setBatteryController(mBatteryController);
((BatteryMeterView) mStatusBarView.findViewById(R.id.battery)).setBatteryController(
mBatteryController);
mKeyguardStatusBar.setBatteryController(mBatteryController);
mHeader.setNextAlarmController(mNextAlarmController);
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mBroadcastReceiver.onReceive(mContext,
new Intent(pm.isScreenOn() ? Intent.ACTION_SCREEN_ON : Intent.ACTION_SCREEN_OFF));
// receive broadcasts
//注册广播接收者,接收关闭系统对话框、屏幕开关
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
IntentFilter demoFilter = new IntentFilter();
if (DEBUG_MEDIA_FAKE_ARTWORK) {
demoFilter.addAction(ACTION_FAKE_ARTWORK);
}
demoFilter.addAction(ACTION_DEMO);
context.registerReceiverAsUser(mDemoReceiver, UserHandle.ALL, demoFilter,
android.Manifest.permission.DUMP, null);
// listen for USER_SETUP_COMPLETE setting (per-user)
resetUserSetupObserver();
// disable profiling bars, since they overlap and clutter the output on app windows
ThreadedRenderer.overrideProperty("disableProfileBars", "true");
// Private API call to make the shadows look better for Recents
ThreadedRenderer.overrideProperty("ambientRatio", String.valueOf(1.5f));
return mStatusBarView;
}
初始化完View后,就添加到窗口,上面也提到过
private void addStatusBarWindow() {
makeStatusBarView();
mStatusBarWindowManager = new StatusBarWindowManager(mContext);
mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());//添加到窗口中。
}
到此createAndAddWindows()这步骤就完成了。
二、addNavigationBar()
// For small-screen devices (read: phones) that lack hardware navigation buttons
private void addNavigationBar() {
if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
if (mNavigationBarView == null) return;
prepareNavigationBarView();//1.prepareNavigationBarView
mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());//添加到窗口中
}
1.prepareNavigationBarView()
这里主要是设置底部导航状态栏点击、触摸、长按事件等监听。
private void prepareNavigationBarView() {
mNavigationBarView.reorient();
//底部导航状态栏点击、触摸、长按事件监听
mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPreloadOnTouchListener);
mNavigationBarView.getRecentsButton().setLongClickable(true);
mNavigationBarView.getRecentsButton().setOnLongClickListener(mLongPressBackRecentsListener);
mNavigationBarView.getBackButton().setLongClickable(true);
mNavigationBarView.getBackButton().setOnLongClickListener(mLongPressBackRecentsListener);
mNavigationBarView.getHomeButton().setOnTouchListener(mHomeActionListener);
mNavigationBarView.getHomeButton().setOnLongClickListener(mLongPressHomeListener);
mAssistManager.onConfigurationChanged();
}
三、PhoneStatusBarPolicy()
这里主要是做一些状态监听,比如sim状态改变、蓝牙链接或断开,音量变化、热点等,然后改变顶部状态栏的icon
public PhoneStatusBarPolicy(Context context, CastController cast, HotspotController hotspot,
UserInfoController userInfoController, BluetoothController bluetooth) {
mContext = context;
mCast = cast;
mHotspot = hotspot;
mBluetooth = bluetooth;
mBluetooth.addStateChangedCallback(this);
mService = (StatusBarManager) context.getSystemService(Context.STATUS_BAR_SERVICE);
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
mUserInfoController = userInfoController;
// listen for broadcasts 闹钟、SIM、TTY等
IntentFilter filter = new IntentFilter();
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(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
filter.addAction(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED);
mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
// listen for user / profile change.
try {
ActivityManagerNative.getDefault().registerUserSwitchObserver(mUserSwitchListener);
} catch (RemoteException e) {
// Ignore
}
// TTY status tty状态
mService.setIcon(SLOT_TTY, R.drawable.stat_sys_tty_mode, 0, null);
mService.setIconVisibility(SLOT_TTY, false);
// bluetooth status 蓝牙
updateBluetooth();
// Alarm clock 闹钟
mService.setIcon(SLOT_ALARM_CLOCK, R.drawable.stat_sys_alarm, 0, null);
mService.setIconVisibility(SLOT_ALARM_CLOCK, false);
// zen
mService.setIcon(SLOT_ZEN, R.drawable.stat_sys_zen_important, 0, null);
mService.setIconVisibility(SLOT_ZEN, false);
// volume 声音
mService.setIcon(SLOT_VOLUME, R.drawable.stat_sys_ringer_vibrate, 0, null);
mService.setIconVisibility(SLOT_VOLUME, false);
updateVolumeZen();
// cast 投射
mService.setIcon(SLOT_CAST, R.drawable.stat_sys_cast, 0, null);
mService.setIconVisibility(SLOT_CAST, false);
mCast.addCallback(mCastCallback);
// hotspot热点
mService.setIcon(SLOT_HOTSPOT, R.drawable.stat_sys_hotspot, 0,
mContext.getString(R.string.accessibility_status_bar_hotspot));
mService.setIconVisibility(SLOT_HOTSPOT, mHotspot.isHotspotEnabled());
mHotspot.addCallback(mHotspotCallback);
// managed profile
mService.setIcon(SLOT_MANAGED_PROFILE, R.drawable.stat_sys_managed_profile_status, 0,
mContext.getString(R.string.accessibility_managed_profile));
mService.setIconVisibility(SLOT_MANAGED_PROFILE, false);
}
四、startKeyguard()
private void startKeyguard() {
KeyguardViewMediator keyguardViewMediator = getComponent(KeyguardViewMediator.class);
mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
mStatusBarWindow, mStatusBarWindowManager, mScrimController);
mKeyguardViewMediatorCallback = keyguardViewMediator.getViewMediatorCallback();
}
这一部分后面单独分析,,目前没了深入了解
历史上的今天
暂无评论...
随机推荐
[摘]查找当前目录下所有文件某一行的内容
前言在做monkey时,会间隔把当前所有应用的内存占用打印出来,因此为了方便查看内存是否有持续增长,会使用命令查看所有dump的文件内容。好记性不如烂笔头正文以下在Window系统中的git bash环境中测试(或者算是Linux环境)find . -type f -name “*.tx...
嫣然若雪:余生,看淡所有,珍惜拥有
现实生活中,有太多的欲望,求不到,爱不得,为自己搭建了牢笼,囚禁在很深的执念里,得不到,放不下。人生本就不易,生活里本就有太多的苦,烦恼不捡自然无,要捡天天有,没有谁能把日子过得一直顺遂。有些人,因为自己的执念,让生活增添不必要的负担;有些人,因为一点小事,让自己活得心烦意乱。人生的痛苦都是自...
SQLite Expert的注册记录
前言SQLite Expert软件很不错,在使用数据库时,这个软件是查看数据库的号帮手,当然,这个也是偶尔使用。这里分析一下网上的注册方法。正文这里介绍下载和注册。下载官方下载对应的位数的SQLite Expert:http://www.sqliteexpert.com/downlo...
android.view.ViewRootImpl$CalledFromWrongThreadException
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.哎,对自己无语了,竟然一时犯了这...
[摘]深入浅出UML类图(三)
本文作者:刘伟 http://blog.csdn.net/lovelion类与类之间的关系(2) 2. 依赖关系依赖(Dependency)关系是一种使用关系,特定事物的改变有可能会影响到使用该事物的其他事物,在需要表示一个事物使用另一个事物时使用依赖关系。大多数情况下,...
常用的Monkey命令
Monkey的概念“猴子测试”是指没有测试经验的人甚至对计算机根本不了解的人(就像猴子一样)不需要知道程序的任何用户交互方面的知识,如果给他一个程序,他就会针对他看到的界面进行操作,其操作是无目的的、乱点乱按的。这种测试方式在产品周期中的早期阶段会找到很多很好的bug,为用户节省不少的时间。...