SystemUI启动流程

init -> ServerManager -> Zygote -> SystemServer -> SystemUIService ->
SystemUIApplication SystemServer启动后,会在SystemServer Main
Thread启动ActivityManagerService,当ActivityManagerService
systemReady后,会去启动SystemUIService。可以看出,startSystemUi不是在SystemServer
Main thread,而是在ActivityManagerService Thread。

\frameworks\base\services\java\com\android\server\SystemServer.java

    /**
     * Starts a miscellaneous grab bag of stuff that has yet to be refactored
     * and organized.
     */
    private void startOtherServices() {
            if (!disableSystemUI) {
                try {
                    Slog.i(TAG, "Status Bar");
                    statusBar = new StatusBarManagerService(context, wm);
                    ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
                } catch (Throwable e) {
                    reportWtf("starting StatusBarManagerService", e);
                }
            }

        mActivityManagerService.systemReady(new Runnable() {
            @Override
            public void run() {
                try {
                    startSystemUi(context);
                } catch (Throwable e) {
                    reportWtf("starting System UI", e);
                }


    static final void startSystemUi(Context context) {
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.android.systemui",
                    "com.android.systemui.SystemUIService"));
        //Slog.d(TAG, "Starting service: " + intent);
        context.startServiceAsUser(intent, UserHandle.OWNER);
}

备注:
context.startServiceAsUser(…)调用的是\frameworks\base\core\java\android\app\ContextImpl.java中的startServiceAsUser(…),而startServiceAsUser(…)调用startServiceCommon(…)
SystemServer在startSystemUi启动SystemUIService后,会走到SystemUIService的onCreate函数。

public class SystemUIService extends Service {
    @Override
    public void onCreate() {
        super.onCreate();
        ((SystemUIApplication) getApplication()).startServicesIfNeeded();
} /* 这个SystemUIService很短,代码不到60行 */

可见SystemUIService调用了SystemUIApplication的startServicesIfNeeded()。
\frameworks\base\packages\SystemUI\src\com\android\systemui\ SystemUIApplication.java

/**
 * Application class for SystemUI.
 */
public class SystemUIApplication extends Application {

    private static final String TAG = "SystemUIService";
    private static final boolean DEBUG = false;

    /**
     * The classes of the stuff to start.
     */
    private final Class<?>[] SERVICES = new Class[] {
            com.android.systemui.keyguard.KeyguardViewMediator.class, // 锁屏机制
            com.android.systemui.recent.Recents.class, // 近期任务
            com.android.systemui.volume.VolumeUI.class, // 音量UI
            com.android.systemui.statusbar.SystemBars.class, // 系统栏
            com.android.systemui.usb.StorageNotification.class, // 存储信息通知
            com.android.systemui.power.PowerUI.class, // 电源UI
            com.android.systemui.media.RingtonePlayer.class // 铃声播放
    }; // 它们并不是真正的Service ,继承了SystemUI.java这个抽象类,复写了start()方法

    /**
     * Hold a reference on the stuff we start.
     */
    private final SystemUI[] mServices = new SystemUI[SERVICES.length];
    private boolean mServicesStarted;
    private boolean mBootCompleted;
    private final Map<Class<?>, Object> mComponents = new HashMap<Class<?>, Object>();

    @Override
    public void onCreate() {
        super.onCreate();
        // Set the application theme that is inherited by all services. Note that setting the
        // application theme in the manifest does only work for activities. Keep this in sync with
        // the theme set there.
        setTheme(R.style.systemui_theme);
        // 注册开机广播
        IntentFilter filter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (mBootCompleted) return;

                if (DEBUG) Log.v(TAG, "BOOT_COMPLETED received");
                unregisterReceiver(this);
                mBootCompleted = true;
                if (mServicesStarted) {
                    final int N = mServices.length;
                    for (int i = 0; i < N; i++) {
                        mServices[i].onBootCompleted();
                    }
                }
            }
        }, filter);
    }

    /**
     * Makes sure that all the SystemUI services are running. If they are already running, this is a
     * no-op. This is needed to conditinally start all the services, as we only need to have it in
     * the main process.
     *
     * <p>This method must only be called from the main thread.</p>
     */
    public void startServicesIfNeeded() {
        if (mServicesStarted) {
            return;
        }

        if (!mBootCompleted) {
            // check to see if maybe it was already completed long before we began
            // see ActivityManagerService.finishBooting()
            if ("1".equals(SystemProperties.get("sys.boot_completed"))) {
                mBootCompleted = true;
                if (DEBUG) Log.v(TAG, "BOOT_COMPLETED was already sent");
            }
        }

        Log.v(TAG, "Starting SystemUI services.");
        final int N = SERVICES.length;
        // for循环逐个启动SystemUI的各个服务(电源UI、音量UI、状态栏等)
        for (int i=0; i<N; i++) {
            Class<?> cl = SERVICES[i];
            if (DEBUG) Log.d(TAG, "loading: " + cl);
            try {
                mServices[i] = (SystemUI)cl.newInstance();
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InstantiationException ex) {
                throw new RuntimeException(ex);
            }
            mServices[i].mContext = this;
            mServices[i].mComponents = mComponents;
            if (DEBUG) Log.d(TAG, "running: " + mServices[i]);
            mServices[i].start(); // 调用各个”服务”的start()方法

            if (mBootCompleted) {
                mServices[i].onBootCompleted();
            }
        }
        mServicesStarted = true;
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        if (mServicesStarted) {
            int len = mServices.length;
            for (int i = 0; i < len; i++) {
                mServices[i].onConfigurationChanged(newConfig);
            }
        }
    }

    @SuppressWarnings("unchecked")
    public <T> T getComponent(Class<T> interfaceType) {
        return (T) mComponents.get(interfaceType);
    }
    // 暴露的接口
    public SystemUI[] getServices() {
        return mServices;
    }
}

下面看SystemBars.java的start()方法

    @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
    }

\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\ServiceMonitor.java

    public ServiceMonitor(String ownerTag, boolean debug,
            Context context, String settingKey, Callbacks callbacks) {
        mTag = ownerTag + ".ServiceMonitor";
        mDebug = debug;
        mContext = context;
        mSettingKey = settingKey;
        mCallbacks = callbacks;
    }

    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.addDataScheme("package");
        mContext.registerReceiver(mBroadcastReceiver, filter);

        mHandler.sendEmptyMessage(MSG_START_SERVICE);
    }

init -> ServerManager -> Zygote -> SystemServer -> SystemUIService -> SystemUIApplication
状态栏启动:
SystemUIApplication -> SystemBars

SystemBars里面createStatusBarFromConfig() {
    ……
    String clsName = mContext.getString(R.string.config_statusBarComponent);
    ……
    cls = mContext.getClassLoader().loadClass(clsName);
    ……
    mStatusBar = (BaseStatusBar) cls.newInstance();
    ……
    mStatusBar.start();
}

config_statusBarComponent在frameworks\base\packages\SystemUI\res\values\config.xml中定义:

<!-- Component to be used as the status bar service.  Must implement the IStatusBar
     interface.  This name is in the ComponentName flattened format (package/class)  -->
<string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.phone.PhoneStatusBar</string>

由此可见,SystemBars里面启动的就是PhoneStatusBar了,PhoneStatusBar继承BaseStatusBar。由Java多态性,mStatusBar.start()实际上就是PhoneStatusBar.start()。下面看一下PhoneStatusBar.start()这个函数的函数体:

@Override
public void start() {
    ……
    super.start(); // calls createAndAddWindows()
    // 添加导航栏
    addNavigationBar();
}

super.start()也就是BaseStatusBar.start(),里面调用了createAndAddWindows(),但这是一个抽象函数,因此会回调至子类PhoneStatusBar的createAndAddWindows(),下面看一下PhoneStatusBar的createAndAddWindows()函数:

@Override
public void createAndAddWindows() {
……
addStatusBarWindow();
    ……
}
private void addStatusBarWindow() {
    makeStatusBarView();
    mStatusBarWindowManager = new StatusBarWindowManager(mContext);
    mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值