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();    }

参考文章

  1. http://blog.csdn.net/qq_31530015/article/details/53507968
  2. http://blog.csdn.net/zhudaozhuan/article/details/50817180
  3. http://blog.csdn.net/yj934672573/article/details/54571704
  4. http://blog.csdn.net/Picasso_L/article/details/69388919
  5. … …
原创粉丝点击