美文网首页
Android8.1 SystemUI启动流程

Android8.1 SystemUI启动流程

作者: 离逝的殇 | 来源:发表于2018-04-30 16:04 被阅读0次

初识SystemUI

SystemUI是为用户提供的系统级别的信息显示与交互的一套UI组件,尽管它的表现形式与普通Android应用程序大相径庭,但它却是以一个apk的其实存在于系统之中,即它与普通android应用程序并没有本质上的区别。它也是通过Android四大组件来接受外界的请求并执行相关操作。

SystemUI启动流程

1.frameworks/base/services/java/com/android/server/SystemServer.java(它是在ZygoteInit中进行创建,并且启动起来的)

 /**
 * The main entry point from zygote.
 */
public static void main(String[] args) {
    new SystemServer().run();
}

接下来,我们看run方法,

 private void run() {
   ...

    // Start services.
    try {
        traceBeginAndSlog("StartServices");
        startBootstrapServices();
        startCoreServices();
        startOtherServices();
        SystemServerInitThreadPool.shutdown();
    } catch (Throwable ex) {
        Slog.e("System", "******************************************");
        Slog.e("System", "************ Failure starting system services", ex);
        throw ex;
    } finally {
        traceEnd();
    }
   ...
}

注意上述方法中的startOtherServices()方法,

/**
 * Starts a miscellaneous grab bag of stuff that has yet to be refactored
 * and organized.
 */
private void startOtherServices() {
     ...
     ...
  try {
            startSystemUi(context, windowManagerF);
        } catch (Throwable e) {
            reportWtf("starting System UI", e);
        }
     ...
     ...
  }

接着看StartSystemUi方法,

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

以上完成了SystemUIService的启动过程。

2.frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIService.java
SystemUIService继承与Service,首先看重写的onCreate方法,

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

    // For debugging RescueParty
    if (Build.IS_DEBUGGABLE && SystemProperties.getBoolean("debug.crash_sysui", false)) {
        throw new RuntimeException();
    }
}

它调用了SystemUIApplication的startServicesIfNeeded()方法,接下来我们看SystemUIApplication中的startServicesIfNeeded()方法
3.frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java

/**
 * 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() {
    startServicesIfNeeded(SERVICES);
}

接着往下跟,

private void startServicesIfNeeded(Class<?>[] services) {
    if (mServicesStarted) {
        return;
    }
     ......
     ......
    final int N = services.length;
    for (int i = 0; i < N; i++) {
        Class<?> cl = services[i];
        if (DEBUG) Log.d(TAG, "loading: " + cl);
        log.traceBegin("StartServices" + cl.getSimpleName());
        long ti = System.currentTimeMillis();
        try {

            Object newService = SystemUIFactory.getInstance().createInstance(cl);
            mServices[i] = (SystemUI) ((newService == null) ? cl.newInstance() : newService);
        } 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();
        log.traceEnd();

        // Warn if initialization of component takes too long
        ti = System.currentTimeMillis() - ti;
        if (ti > 1000) {
            Log.w(TAG, "Initialization of " + cl.getName() + " took " + ti + " ms");
        }
        if (mBootCompleted) {
            mServices[i].onBootCompleted();
        }
    }
   ...
}

可以看到,上述代码中,有一个for循环的遍历,那么这个service[i]是什么呢?我们可以找到代码中初始化的地方,

/**
 * The classes of the stuff to start.
 */
private final Class<?>[] SERVICES = new Class[] {
        Dependency.class,
        NotificationChannels.class,
        CommandQueue.CommandQueueStart.class,
        KeyguardViewMediator.class,
        Recents.class,
        VolumeUI.class,
        Divider.class,
        SystemBars.class,
        StorageNotification.class,
        PowerUI.class,
        RingtonePlayer.class,
        KeyboardUI.class,
        PipUI.class,
        ShortcutKeyDispatcher.class,
        VendorServices.class,
        GarbageMonitor.Service.class,
        LatencyTester.class,
        GlobalActionsComponent.class,
        RoundedCorners.class,
};

这里是拿到每个和 SystemUI 相关的类的反射,存到了 service[] 里,然后赋值给cl,紧接着将通过反射将其转化为具体类的对象,存到了mService[i]数组里,最后对象调 start() 方法启动相关类的服务,启动完成后,回调 onBootCompleted( ) 方法。
mService[i] 里的值不同时,调用的 start() 方法也不相同。
以上就是SystemUI启动的大致流程,具体的对应的每个不同的会在后续做详细的分析。

ps:其实接触开发的时间并不久,而framework更是刚接触几天,压力其实挺大的。但每份努力都是为了成就最后的自己吧,共勉!!!

相关文章

网友评论

      本文标题:Android8.1 SystemUI启动流程

      本文链接:https://www.haomeiwen.com/subject/mouzlftx.html