SystemUI 7.0学习笔记二-状态栏和导航栏
来源:互联网 发布:python 提取文件路径 编辑:程序博客网 时间:2024/06/05 20:51
状态栏和导航栏的启动
SystemUI 7.0学习笔记一中SERVICES中类的名字就可以大致猜出来它们的功能,对!本节的主角就是com.android.systemui.statusbar.SystemBars.class。
首先看一张图来个全面的把握,
SystemBars的start()会new一个ServiceMonitor对象,接着会调用其start()。
public class SystemBars extends SystemUI implements ServiceMonitor.Callbacks { ...... @Override public void start() { if (DEBUG) Log.d(TAG, "start"); mServiceMonitor = new ServiceMonitor(TAG, DEBUG, mContext, Settings.Secure.BAR_SERVICE_COMPONENT, this); mServiceMonitor.start(); // will call onNoService if no remote service is found } ......}
ServiceMonitor的start()发消息给Handler处理,
public void start() { ...... mHandler.sendEmptyMessage(MSG_START_SERVICE); }
private final Handler mHandler = new Handler() { public void handleMessage(Message msg) { switch(msg.what) { case MSG_START_SERVICE: startService(); break; ...... } } };
startService()中mCallbacks.onNoService();的mCallbacks就是创建ServiceMonitor时传入的this(SystemBars)。
private void startService() { mServiceName = getComponentNameFromSetting(); if (mDebug) Log.d(mTag, "startService mServiceName=" + mServiceName); if (mServiceName == null) { mBound = false; mCallbacks.onNoService(); } else { long delay = mCallbacks.onServiceStartAttempt(); mHandler.sendEmptyMessageDelayed(MSG_CONTINUE_START_SERVICE, delay); } }
回调SystemBars的onNoService()里创建StatusBar,
public class SystemBars extends SystemUI implements ServiceMonitor.Callbacks { ...... @Override public void onNoService() { if (DEBUG) Log.d(TAG, "onNoService"); createStatusBarFromConfig(); // fallback to using an in-process implementation } ......}
在createStatusBarFromConfig()里会获取一个config_statusBarComponent的字符串值,这个值就是PhoneStatusBar的clasName,
private void createStatusBarFromConfig() { if (DEBUG) Log.d(TAG, "createStatusBarFromConfig"); final String clsName = mContext.getString(R.string.config_statusBarComponent); if (clsName == null || clsName.length() == 0) { throw andLog("No status bar component configured", null); } Class<?> cls = null; try { cls = mContext.getClassLoader().loadClass(clsName); } catch (Throwable t) { throw andLog("Error loading status bar component: " + clsName, t); } try { // 创建实例 mStatusBar = (BaseStatusBar) cls.newInstance(); } catch (Throwable t) { throw andLog("Error creating status bar component: " + clsName, t); } mStatusBar.mContext = mContext; mStatusBar.mComponents = mComponents; // start mStatusBar.start(); if (DEBUG) Log.d(TAG, "started " + mStatusBar.getClass().getSimpleName()); }
<string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.phone.PhoneStatusBar</string>
所以,这里的mStatusBar是PhoneStatusBar实例。
PhoneStatusBar的start():
public class PhoneStatusBar extends BaseStatusBar implements DemoMode, DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener, HeadsUpManager.OnHeadsUpChangedListener { ...... @Override public void start() { ...... super.start(); // calls createAndAddWindows() ...... addNavigationBar(); }}
PhoneStatusBar的start()会回调父类BaseStatusBar 的start(),
super.start():
public abstract class BaseStatusBar extends SystemUI implements CommandQueue.Callbacks, ActivatableNotificationView.OnActivatedListener, ExpandableNotificationRow.ExpansionLogger, NotificationData.Environment, ExpandableNotificationRow.OnExpandClickListener, OnGutsClosedListener { ...... // 实例化IStatusBarService mBarService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); ...... // Connect in to the status bar manager service mCommandQueue = new CommandQueue(this); // 注意上面的注释 int[] switches = new int[9]; ArrayList<IBinder> binders = new ArrayList<IBinder>(); ArrayList<String> iconSlots = new ArrayList<>(); ArrayList<StatusBarIcon> icons = new ArrayList<>(); Rect fullscreenStackBounds = new Rect(); Rect dockedStackBounds = new Rect(); try { // register后,StatusBarManagerService(IStatusBarService的实例)就可以和BaseStatusBar亲密交流了,CommandQueue的注释大概就是这个意思。 mBarService.registerStatusBar(mCommandQueue, iconSlots, icons, switches, binders, fullscreenStackBounds, dockedStackBounds); } catch (RemoteException ex) { // If the system process isn't there we're doomed anyway. } // 抽象方法 createAndAddWindows();}
BaseStatusBar获取了IStatusBarService的实例-StatusBarManagerService,并注册一些信息到StatusBarManagerService中,BaseStatusBar通过CommandQuene间接将自己注册到StatusBarManagerService,而StatusBarManagerService会把操作状态栏和导航栏的请求通过CommandQuene再转发给BaseStatusBar。
另外,为了保证SystemUI意外退出后不会发生信息丢失,StatusBarManagerService保存了所有需要状态栏与导航栏进行显示或处理的信息副本,在上述注册的过程中一并取回了。
StatusBarManagerService的registerStatusBar()就是做一些数据的初始化:
public class StatusBarManagerService extends IStatusBarService.Stub { ...... // ================================================================================ // Callbacks from the status bar service. // ================================================================================ @Override public void registerStatusBar(IStatusBar bar, List<String> iconSlots, List<StatusBarIcon> iconList, int switches[], List<IBinder> binders, Rect fullscreenStackBounds, Rect dockedStackBounds) { enforceStatusBarService(); Slog.i(TAG, "registerStatusBar bar=" + bar); mBar = bar; synchronized (mIcons) { for (String slot : mIcons.keySet()) { iconSlots.add(slot); iconList.add(mIcons.get(slot)); } } synchronized (mLock) { switches[0] = gatherDisableActionsLocked(mCurrentUserId, 1); switches[1] = mSystemUiVisibility; switches[2] = mMenuVisible ? 1 : 0; switches[3] = mImeWindowVis; switches[4] = mImeBackDisposition; switches[5] = mShowImeSwitcher ? 1 : 0; switches[6] = gatherDisableActionsLocked(mCurrentUserId, 2); switches[7] = mFullscreenStackSysUiVisibility; switches[8] = mDockedStackSysUiVisibility; binders.add(mImeToken); fullscreenStackBounds.set(mFullscreenStackBounds); dockedStackBounds.set(mDockedStackBounds); } } ......}
用一张图表示下这几者的关系:
让我们回到抽象方法createAndAddWindows(),
/** * Create all windows necessary for the status bar (including navigation, overlay panels, etc) * and add them to the window manager. */ protected abstract void createAndAddWindows();
PhoneStatusBar实现了父类BaseStatusBar中的createAndAddWindows(),
@Override public void createAndAddWindows() { addStatusBarWindow(); }
继续看下addStatusBarWindow()实现:
private void addStatusBarWindow() { makeStatusBarView(); mStatusBarWindowManager = new StatusBarWindowManager(mContext); mRemoteInputController = new RemoteInputController(mStatusBarWindowManager, mHeadsUpManager); mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight()); }
接着看makeStatusBarView()的实现,发现调用了 inflateStatusBarWindow(context):
protected void inflateStatusBarWindow(Context context) { mStatusBarWindow = (StatusBarWindowView) View.inflate(context, R.layout.super_status_bar, null); }
inflate完布局后,就会添加mStatusBarWindow 到WindowManager里。到这里,状态栏就启动完毕了。后面会抽时间补充下布局相关的代码说明。。。
下面看下导航栏的启动
PhoneStatusBar.addNavigationBar():
protected void addNavigationBar() { if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mNavigationBarView); if (mNavigationBarView == null) return; ...... prepareNavigationBarView(); mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams()); }
在这个方法里先初始化导航栏,然后把导航栏添加到WindowManager,prepareNavigationBarView()对三个按键做了事件监听。
private void prepareNavigationBarView() { mNavigationBarView.reorient(); ButtonDispatcher recentsButton = mNavigationBarView.getRecentsButton(); recentsButton.setOnClickListener(mRecentsClickListener); recentsButton.setOnTouchListener(mRecentsPreloadOnTouchListener); recentsButton.setLongClickable(true); recentsButton.setOnLongClickListener(mRecentsLongClickListener); ButtonDispatcher backButton = mNavigationBarView.getBackButton(); backButton.setLongClickable(true); backButton.setOnLongClickListener(mLongPressBackListener); ButtonDispatcher homeButton = mNavigationBarView.getHomeButton(); homeButton.setOnTouchListener(mHomeActionListener); homeButton.setOnLongClickListener(mLongPressHomeListener); mAssistManager.onConfigurationChanged(); }
参考文章
- http://blog.csdn.net/qq_31530015/article/details/53507968
- http://blog.csdn.net/zhudaozhuan/article/details/50817180
- http://blog.csdn.net/yj934672573/article/details/54571704
- http://blog.csdn.net/Picasso_L/article/details/69388919
- … …
- SystemUI 7.0学习笔记二-状态栏和导航栏
- [RK3288][Android6.0] SystemUI加载过程(状态栏和导航栏)
- Android 7.0 SystemUI 之启动和状态栏和导航栏简介
- Android 7.0 SystemUI 之启动和状态栏和导航栏简介
- iOS开发中的导航栏和状态栏学习笔记
- IOS7导航栏和状态栏学习
- 状态栏和导航栏
- 导航栏和状态栏
- Android菜鸟之学习android源码之二(SystemUI导航栏初步认识及修改)
- Android笔记:导航栏和状态栏的透明度设置
- SystemUI中状态栏跟导航栏隐藏显示控制方法及效果示例
- SystemUI中状态栏跟导航栏隐藏显示控制方法及效果示例
- 导航--状态栏和导航栏颜色变化
- 定制导航栏和状态栏
- 自定义导航栏和状态栏
- iOS导航栏和状态栏
- 管理状态栏和导航栏
- 定制导航栏和状态栏
- 面试题集锦
- codeforces round #415 C.Do you want a Date?
- linux运维-postfix邮件的处理
- 深入理解Spring Redis的使用 (六)、用Spring Aop 实现注解Dao层的自动Spring Redis缓存
- 2017年 3月到2017年6月
- SystemUI 7.0学习笔记二-状态栏和导航栏
- docker入门安装
- 将access_token保存在哪?
- unity3d施加牛顿力
- 嵌入式Linux应用程序开发详解-笔记1
- 一个正整数分解为几个连续的正整数之和
- 集合类
- 算法训练 最短路(spfa+slf优化)
- hdu 1280 堆排序