Android状态栏的启动

com.android.systemui.SystemUIService.java

查看代码发现,启动机器,会去启动SystemUI的SystemUIService,而这个service的入口就是onCreate()方法。

public void onCreate() {
    super.onCreate();
    ((SystemUIApplication) getApplication()).startServicesIfNeeded();
} 

com.android.systemui.SystemUIApplication.java

创建了一个集合,这个集合里面装的都是SystenUI的子类的全类名,但是有一个例外,”Divider.class”而没有写成”com.android.systemui.stackdivider.Divider.class” ?

private final SystemUI[] mServices = new SystemUI[SERVICES.length];
private final Class<?>[] SERVICES = new Class[] {
        com.android.systemui.tuner.TunerService.class, 
        com.android.systemui.keyguard.KeyguardViewMediator.class, 
        com.android.systemui.recents.Recents.class,
        com.android.systemui.volume.VolumeUI.class,
        Divider.class, //多窗口
        com.android.systemui.statusbar.SystemBars.class,
        com.android.systemui.usb.StorageNotification.class,
        com.android.systemui.power.PowerUI.class,
        com.android.systemui.media.RingtonePlayer.class,
        com.android.systemui.keyboard.KeyboardUI.class,
        com.android.systemui.tv.pip.PipUI.class,
        com.android.systemui.shortcut.ShortcutKeyDispatcher.class
};
public void startServicesIfNeeded() {
        startServicesIfNeeded(SERVICES);
}

根据SERVICES这个集合提供的全类名,通过反射的方式来得到具体实例,然后再调用start()方法启动相应模块。其中onBootCompleted()这个方法只有recent、keyguard模块实现了。

private void startServicesIfNeeded(Class<?>[] services) {
    if (mServicesStarted) {
        return;
    }
    final int N = services.length;
    for (int i=0; i<N; i++) {
        Class<?> cl = services[i];
        try {
            Object newService = SystemUIFactory.getInstance().createInstance(cl);
            mServices[i] = (SystemUI) ((newService == null) ? cl.newInstance() : newService);
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        } 
        mServices[i].mContext = this;
        mServices[i].mComponents = mComponents;
        mServices[i].start();
        if (mBootCompleted) {
            mServices[i].onBootCompleted();
        }
    }
    mServicesStarted = true;
}

com.android.systemui.statusbar.SystemBars

从SystemUI的流程分析中知道,在启动SystemUI的时候会指定启动SystemBars.class这个类的start()方法。

private ServiceMonitor mServiceMonitor;
public void start() {
    mServiceMonitor = new ServiceMonitor(TAG, DEBUG,
            mContext, Settings.Secure.BAR_SERVICE_COMPONENT, this);
    mServiceMonitor.start();  // will call onNoService if no remote service is found
}

com.android.systemui.statusbar.ServiceMonitor

这个类的start()方法,主要就是这三件事,监听文件、注册广播、启动服务(实际没有启动服务?)

public void start() {
    // listen for setting changes
    ContentResolver cr = mContext.getContentResolver();
    cr.registerContentObserver(Settings.Secure.getUriFor(mSettingKey),
            false /*notifyForDescendents*/, mSettingObserver, UserHandle.USER_ALL);

    // listen for package/component changes
    IntentFilter filter = new IntentFilter();
    filter.addAction(Intent.ACTION_PACKAGE_ADDED);//一个新应用包已经安装在设备上,数据包括包名(最新安装的包程序不能接收到这个广播)
    filter.addAction(Intent.ACTION_PACKAGE_CHANGED);//一个新版本的应用安装到设备,替换之前已经存在的版本
    filter.addAction(Intent.ACTION_PACKAGE_REMOVED);//一个已存在的应用程序包已经从设备上移除,包括包名(正在被安装的包程序不能接收到这个广播)
    filter.addDataScheme("package");
    mContext.registerReceiver(mBroadcastReceiver, filter);

    mHandler.sendEmptyMessage(MSG_START_SERVICE);//会调用startService()方法
}

在startService()方法先是试图获取服务的类名,但是通过重启机器的日志发现这个
mServiceName ==null,所以还是会回调到上一个类的onNoService()方法。

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

com.android.systemui.statusbar.SystemBars

因为SystemBars实现了上面的Callbacks接口,所以会调到这个方法。

@Override
public void onNoService() {
    createStatusBarFromConfig();  // fallback to using an in-process implementation
}

通过查找发现config_statusBarComponent==com.android.systemui.statusbar.phone.PhoneStatusBar,所以下面的cls.newInstance()得到的实际上就是PhoneStatusBar的实例,然后调用其start()方法。之后就是进入PhoneStatusBar类了。

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;
    mStatusBar.start();
    if (DEBUG) Log.d(TAG, "started " + mStatusBar.getClass().getSimpleName());
}

com.android.systemui.statusbar.phone.PhoneStatusBar

PhoneStatusBar extends BaseStatusBar,而在BASEStatusBar的start()方法里面调用了createAndAddWindows(),并且由PhoneStatusBar 来实现该方法。

@Override
public void start() {
...
    super.start(); // calls createAndAddWindows()
...
}
@Override
public void createAndAddWindows() {
    addStatusBarWindow();
}

这个方法的主要作用,先是view的一些初始化操作,然后再将StatusBarWindowView添加到StatusBarWindowManager上。

private void addStatusBarWindow() {
    makeStatusBarView();
    mStatusBarWindowManager = new StatusBarWindowManager(mContext);
    mRemoteInputController = new RemoteInputController(mStatusBarWindowManager,
            mHeadsUpManager);
    mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
}

这个方法的主要作用是对PhoneStatusBarView 的初始化,并返回这个对象,其中初始化的东西比较多,比如:通知栏、状态栏

protected PhoneStatusBarView makeStatusBarView() {
    ...
    inflateStatusBarWindow(context);//加载布局mStatusBarWindow = R.layout.**super_status_bar
    ...
    mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(
                R.id.notification_panel);//通知栏
    //状态栏
    mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
    ...
    mBatteryController = createBatteryController();//电池状态监听广播(可以获取电池信息)
    //网络监听
    mNetworkController = new NetworkControllerImpl(mContext, mHandlerThread.getLooper());
    mHotspotController = new HotspotControllerImpl(mContext);//热点控制器
    mBluetoothController = new BluetoothControllerImpl(mContext, getLooper());//蓝牙控制器
    mSecurityController = new SecurityControllerImpl(mContext);//安全控制器
    ......//各种状态栏图标的控制器
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值