android 6.0 SystemUI源码分析(4)-StatusBar显示流程


android 6.0 SystemUI源码分析(4)-StatusBar显示流程
转载 http://blog.csdn.net/zhudaozhuan/article/details/50829736

1.StatusBar启动

StatusBar继承于SystemUI,在SystemUIApplication会启动SysteBar.

mServices[i].start();

SystemBar.java
[java] view plain copy
  1. @Override  
  2.    public void start() {  
  3.        if (DEBUG) Log.d(TAG, "start");  
  4.        mServiceMonitor = new ServiceMonitor(TAG, DEBUG,  
  5.                mContext, Settings.Secure.BAR_SERVICE_COMPONENT, this);  
  6.        mServiceMonitor.start();  // will call onNoService if no remote service is found  
  7.    }  
在start函数会实例化ServiceMonitor以及start ServieMonitor。

ServiceMonitor.java
[java] view plain copy
  1. public void start() {  
  2.       // listen for setting changes  
  3.       ContentResolver cr = mContext.getContentResolver();  
  4.       cr.registerContentObserver(Settings.Secure.getUriFor(mSettingKey),  
  5.               false /*notifyForDescendents*/, mSettingObserver, UserHandle.USER_ALL);  
  6.   
  7.       // listen for package/component changes  
  8.       IntentFilter filter = new IntentFilter();  
  9.       filter.addAction(Intent.ACTION_PACKAGE_ADDED);  
  10.       filter.addAction(Intent.ACTION_PACKAGE_CHANGED);  
  11.       filter.addAction(Intent.ACTION_PACKAGE_REMOVED);  
  12.       filter.addDataScheme("package");  
  13.       mContext.registerReceiver(mBroadcastReceiver, filter);  
  14.   
  15.       mHandler.sendEmptyMessage(MSG_START_SERVICE);  
  16.   }  
这个函数主要做两件事情:
1)监听apk的安装卸载,即apk变化事件
2)发送MSG_START_SERVICE,启动service

ServiceMonitor.java
[java] view plain copy
  1. private void startService() {  
  2.        mServiceName = getComponentNameFromSetting();  
  3.        if (mDebug) Log.d(mTag, "startService mServiceName=" + mServiceName);  
  4.        if (mServiceName == null) {  
  5.            mBound = false;  
  6.            mCallbacks.onNoService();  
  7.        } else {  
  8.            long delay = mCallbacks.onServiceStartAttempt();  
  9.            mHandler.sendEmptyMessageDelayed(MSG_CONTINUE_START_SERVICE, delay);  
  10.        }  
  11.    }  
当ServiceName为NULL时,会call到callbacks的onNoService函数。
不等于NULL,在下面的Handler消息也会call到callBacks的onNoService函数。

从SystemBars.java的继承关系可以看到:
public class SystemBars extends SystemUI implements ServiceMonitor.Callbacks
最终会call到SystemBars.java的onNoService函数

SystemBars.java
[java] view plain copy
  1. @Override  
  2.    public void onNoService() {  
  3.        if (DEBUG) Log.d(TAG, "onNoService");  
  4.        createStatusBarFromConfig();  // fallback to using an in-process implementation  
  5.    }  
createStatusBarFromConfig函数实现:
[java] view plain copy
  1. private void createStatusBarFromConfig() {  
  2.        if (DEBUG) Log.d(TAG, "createStatusBarFromConfig");  
  3.        final String clsName = mContext.getString(R.string.config_statusBarComponent);  
  4.        if (clsName == null || clsName.length() == 0) {  
  5.            throw andLog("No status bar component configured", null);  
  6.        }  
  7.        Class cls = null;  
  8.        try {  
  9.            cls = mContext.getClassLoader().loadClass(clsName);  
  10.        } catch (Throwable t) {  
  11.            throw andLog("Error loading status bar component: " + clsName, t);  
  12.        }  
  13.        try {  
  14.            mStatusBar = (BaseStatusBar) cls.newInstance();  
  15.        } catch (Throwable t) {  
  16.            throw andLog("Error creating status bar component: " + clsName, t);  
  17.        }  
  18.        mStatusBar.mContext = mContext;  
  19.        mStatusBar.mComponents = mComponents;  
  20.        mStatusBar.start();  
  21.        if (DEBUG) Log.d(TAG, "started " + mStatusBar.getClass().getSimpleName());  
  22.    }  
会call到BaseStatusBar的start函数

BaseStatusBars.java
public void start() {
...
//各种实例化和初始化
createAndAddWindows();
}


2.StatusBars创建

在BaseStausBars中,createAndAddWindows函数是抽象函数,看来是call到子类的createAndAddWindows函数。
在SysemUI中,继承BaseStatusBars的类有:PhoneStatusBar和TvStatusBar,其中TvStatusBar是空实现,因此主要看PhoneStatusBar

PhoneStatusBar.java
[java] view plain copy
  1. @Override  
  2.     public void createAndAddWindows() {  
  3.         addStatusBarWindow();  
  4.     }  
  5.   
  6.     private void addStatusBarWindow() {  
  7.         makeStatusBarView();  
  8.         mStatusBarWindowManager = new StatusBarWindowManager(mContext);  
  9.         mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());  
  10.     }  
1)makeStatusBarView函数代码很长,因为PhoneStatusBarView除了状态栏那一条之外,还包含Notification Panel,Heads up Panel以及包含drag行为。
主要还是实例化PhoneStatusBarView中各种UI控件。
2)StatusBarWindowManager类的add函数负责为PhoneStatusBarView新建Window,包括window大小,位置,是否透明等属性。

这里先分析一下makeStatusBarView函数,代码太长,不全部粘贴。
(1)获取系统显示参数
updateDisplaySize();
[java] view plain copy
  1. // called by makeStatusbar and also by PhoneStatusBarView  
  2. void updateDisplaySize() {  
  3.     mDisplay.getMetrics(mDisplayMetrics);  
  4.     mDisplay.getSize(mCurrentDisplaySize);  
  5.     if (DEBUG_GESTURES) {  
  6.         mGestureRec.tag("display",  
  7.                 String.format("%dx%d", mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));  
  8.     }  
  9. }  
获取系统分辨率,屏幕密度,便于根据不同的显示参数计算响应的值进行显示。
(2)更新Panels资源数据
StatusBar这个图层包含很多的Panel,在创建PhoneStatusBarView时需要更新Panels数据。
updateResources();
[java] view plain copy
  1. /** 
  2.  * Reload some of our resources when the configuration changes. 
  3.  * 
  4.  * We don't reload everything when the configuration changes -- we probably 
  5.  * should, but getting that smooth is tough.  Someday we'll fix that.  In the 
  6.  * meantime, just update the things that we know change. 
  7.  */  
  8. void updateResources() {  
  9.     // Update the quick setting tiles  
  10.     if (mQSPanel != null) {  
  11.         mQSPanel.updateResources();  
  12.     }  
  13.   
  14.     loadDimens();  
  15.   
  16.     if (mNotificationPanel != null) {  
  17.         mNotificationPanel.updateResources();  
  18.     }  
  19.     if (mBrightnessMirrorController != null) {  
  20.         mBrightnessMirrorController.updateResources();  
  21.     }  
  22. }  
QSPanel是快捷设置panel,一些主要应用,可以通过点击QSPanel的Button去进入apk,android和iphone都有这样的设计。
NotificationPanel是通知消息显示的Panel,在有消息(系统或apk发送Notification),会在Panel里面显示,用户可以删除,或点击消息进入apk。
BrightnessMirrorController是控制亮度的Panel
(3)注册系统的事件广播
 // 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);
(4)Panels & Views实例化以及事件注册


3.StatusBar显示

显示主要是call StatusBarWindowManager类的add函数。
StatusBarWindowManager.java
[java] view plain copy
  1. /** 
  2.     * Adds the status bar view to the window manager. 
  3.     * 
  4.     * @param statusBarView The view to add. 
  5.     * @param barHeight The height of the status bar in collapsed state. 
  6.     */  
  7.    public void add(View statusBarView, int barHeight) {  
  8.   
  9.        // Now that the status bar window encompasses the sliding panel and its  
  10.        // translucent backdrop, the entire thing is made TRANSLUCENT and is  
  11.        // hardware-accelerated.  
  12.        mLp = new WindowManager.LayoutParams(  
  13.                ViewGroup.LayoutParams.MATCH_PARENT,  
  14.                barHeight,  
  15.                WindowManager.LayoutParams.TYPE_STATUS_BAR,  
  16.                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE  
  17.                        | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING  
  18.                        | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH  
  19.                        | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH  
  20.                        | WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,  
  21.                PixelFormat.TRANSLUCENT);  
  22.        mLp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;  
  23.        mLp.gravity = Gravity.TOP;  
  24.        mLp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;  
  25.        mLp.setTitle("StatusBar");  
  26.        mLp.packageName = mContext.getPackageName();  
  27.        mStatusBarView = statusBarView;  
  28.        mBarHeight = barHeight;  
  29.        mWindowManager.addView(mStatusBarView, mLp);  
  30.        mLpChanged = new WindowManager.LayoutParams();  
  31.        mLpChanged.copyFrom(mLp);  
  32.    }  
barHeight表示状态栏的宽度,在dimen里面可以配置:
 public int getStatusBarHeight() {
        if (mNaturalBarHeight < 0) {
            final Resources res = mContext.getResources();
            mNaturalBarHeight =
                    res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
        }
        return mNaturalBarHeight;
    }
若不想显示,可以设置为0

你可能感兴趣的:(android,系统,SystemUI,frameworks,systemui)