7

Android Systrace 基础知识(4) - SystemServer 解读

 3 years ago
source link: https://zhuanlan.zhihu.com/p/142792393
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Android Systrace 基础知识(4) - SystemServer 解读

吾辈心中亦有惑!公众号:AndroidPerformance

本文是 Systrace 系列文章的第四篇,主要是对 SystemServer 进行简单介绍,介绍了 SystemServer 中几个比较重要的线程,由于 Input 和 Binder 比较重要,所以单独拿出来讲,在这里就没有再涉及到。

本系列的目的是通过 Systrace 这个工具,从另外一个角度来看待 Android 系统整体的运行,同时也从另外一个角度来对 Framework 进行学习。也许你看了很多讲 Framework 的文章,但是总是记不住代码,或者不清楚其运行的流程,也许从 Systrace 这个图形化的角度,你可以理解的更深入一些。

系列文章目录

正文

窗口动画

Systrace 中的 SystemServer 一个比较重要的地方就是窗口动画,由于窗口归 SystemServer 来管,那么窗口动画也就是由 SystemServer 来进行统一的处理,其中涉及到两个比较重要的线程,Android.Anim 和 Android.Anim.if 这两个线程,这两个线程的基本知识在下面有讲。

这里我们以「应用启动」为例,查看窗口时如何在两个线程之间进行切换(Android P 里面,应用的启动动画由 Launcher 和应用自己的第一帧组成,之前是在 SystemServer 里面的,现在多任务的动画为了性能部分移到了 Launcher 去实现)

首先我们点击图标启动应用的时候,由于 App 还在启动,Launcher 首先启动一个 StartingWindow,等 App 的第一帧绘制好了之后,再切换到 App 的窗口动画

Launcher 动画

此时对应的,App 正在启动

从上图可以看到,应用第一帧已经准备好了,接下来看对应的 SystemServer ,可以看到应用启动第一帧绘制完成后,动画切换到 App 的 Window 动画

ActivityManagerService

AMS 和 WMS 算是 SystemServer 中最繁忙的两个 Service 了,与 AMS 相关的 Trace 一般会用 TRACE_TAG_ACTIVITY_MANAGER 这个 TAG,在 Systrace 中的名字是 ActivityManager

下面是启动一个新的进程的时候,AMS 的输出

在进程和四大组件的各种场景一般都会有对应的 Trace 点来记录,比如大家熟悉的 ActivityStart、ActivityResume、activityStop 等,这些 Trace 点有一些在应用进程,有一些在 SystemServer 进程,所以大家在看 Activity 相关的代码逻辑的时候,需要不断在这两个进程之间进行切换,这样才能从一个整体的角度来看应用的状态变化和 SystemServer 在其中起到的作用。

WindowManagerService

与 AMS 相关的 Trace 一般会用 TRACE_TAG_WINDOW_MANAGER 这个 TAG,在 Systrace 中 WindowManagerService 在 SystemServer 中多在 对应的 Binder 中出现,比如下面应用启动的时候,relayoutWindow 的 Trace 输出

在 Window 的各种场景一般都会有对应的 Trace 点来记录,比如大家熟悉的 relayoutWIndow、performLayout、prepareToDisplay 等

Input

Input 是 SystemServer 线程里面非常重要的一部分,主要是由 InputReader 和 InputDispatcher 这两个 Native 线程组成,关于这一部分在 Systrace 基础知识 - Input 解读 里面已经详细讲过,这里就不再详细讲了

Binder

SystemServer 由于提供大量的基础服务,所以进程间的通信非常繁忙,且大部分通信都是通过 Binder ,所以 Binder 在 SystemServer 中的作用非常关键,很多时候当后台有大量的 App 存在的时候,SystemServer 就会由于 Binder 通信和锁竞争,导致系统或者 App 卡顿。关于这一部分在 Binder 和锁竞争解读 里面已经详细讲过,这里就不再详细讲了

HandlerThread

BackgroundThread

com/android/internal/os/BackgroundThread.java

private BackgroundThread() {
    super("android.bg", android.os.Process.THREAD_PRIORITY_BACKGROUND);
}

Systrace 中的 BackgroundThread

BackgroundThread 在系统中使用比较多,许多对性能没有要求的任务,一般都会放到 BackgroundThread 中去执行

ServiceThread

ServiceThread 继承自 HandlerThread ,下面介绍的几个工作线程都是继承自 ServiceThread ,分别实现不同的功能,根据线程功能不同,其线程优先级也不同:UIThread、IoThread、DisplayThread、AnimationThread、FgThread、SurfaceAnimationThread

每个 Thread 都有自己的 Looper 、Thread 和 MessageQueue,互相不会影响。Android 系统根据功能,会使用不同的 Thread 来完成。

UiThread

com/android/server/UiThread.java

private UiThread() {
    super("android.ui", Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
}

Systrace 中的 UiThread

UiThread 被使用的地方如下,具体的功能可以自己去源码里面查看,关键字是 UiThread.get()

IoThread

com/android/server/IoThread.java

private IoThread() {
    super("android.io", android.os.Process.THREAD_PRIORITY_DEFAULT, true /*allowIo*/);
}

IoThread 被使用的地方如下,具体的功能可以自己去源码里面查看,关键字是 IoThread.get()

DisplayThread

com/android/server/DisplayThread.java

private DisplayThread() {
    // DisplayThread runs important stuff, but these are not as important as things running in
    // AnimationThread. Thus, set the priority to one lower.
    super("android.display", Process.THREAD_PRIORITY_DISPLAY + 1, false /*allowIo*/);
}

Systrace 中的 DisplayThread



AnimationThread

com/android/server/AnimationThread.java

private AnimationThread() {
    super("android.anim", THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
}

Systrace 中的 AnimationThread

file:///Users/gaojack/blog/source/images/15808255124784.jpg

AnimationThread 在源码中的使用,可以看到 WindowAnimator 的动画执行也是在 AnimationThread 线程中的,Android P 增加了一个 SurfaceAnimationThread 来分担 AnimationThread 的部分工作,来提高 WindowAnimation 的动画性能

FgThread

com/android/server/FgThread.java

private FgThread() {
    super("android.fg", android.os.Process.THREAD_PRIORITY_DEFAULT, true /*allowIo*/);
}

Systrace 中的 FgThread

FgThread 在源码中的使用,可以自己搜一下,下面是具体的使用的一个例子

FgThread.getHandler().post(() -> {
    synchronized (mLock) {
        if (mStartedUsers.get(userIdToLockF) != null) {
            Slog.w(TAG, "User was restarted, skipping key eviction");
            return;
        }
    }
    try {
        mInjector.getStorageManager().lockUserKey(userIdToLockF);
    } catch (RemoteException re) {
        throw re.rethrowAsRuntimeException();
    }
    if (userIdToLockF == userId) {
        for (final KeyEvictedCallback callback : keyEvictedCallbacks) {
            callback.keyEvicted(userId);
        }
    }
});

SurfaceAnimationThread

com/android/server/wm/SurfaceAnimationThread.java
private SurfaceAnimationThread() {
    super("android.anim.lf", THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
}

Systrace 中的 SurfaceAnimationThread

SurfaceAnimationThread 的名字叫 android.anim.lf , 与 android.anim 有区别,

这个 Thread 主要是执行窗口动画,用于分担 android.anim 线程的一部分动画工作,减少由于锁导致的窗口动画卡顿问题,具体的内容可以看这篇文章:Android P——LockFreeAnimation

SurfaceAnimationRunner(@Nullable AnimationFrameCallbackProvider callbackProvider,
        AnimatorFactory animatorFactory, Transaction frameTransaction,
        PowerManagerInternal powerManagerInternal) {
    SurfaceAnimationThread.getHandler().runWithScissors(() -> mChoreographer = getSfInstance(),
            0 /* timeout */);
    mFrameTransaction = frameTransaction;
    mAnimationHandler = new AnimationHandler();
    mAnimationHandler.setProvider(callbackProvider != null
            ? callbackProvider
            : new SfVsyncFrameCallbackProvider(mChoreographer));
    mAnimatorFactory = animatorFactory != null
            ? animatorFactory
            : SfValueAnimator::new;
    mPowerManagerInternal = powerManagerInternal;
}

关于我 && 博客

「一个人可以走的更快 , 一群人可以走的更远」


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK