Android Systrace 基礎知識(4) - SystemServer 解讀

本文是 Systrace 系列文章的第四篇,主要是對 SystemServer 進行簡單介紹,介紹了 SystemServer 中幾個比較重要的線程,由於 Input 和 Binder 比較重要,所以單獨拿出來講,在這裏就沒有再涉及到。

本系列的目的是通過 Systrace 這個工具,從另外一個角度來看待 Android 系統整體的運行,同時也從另外一個角度來對 Framework 進行學習。也許你看了很多講 Framework 的文章,但是總是記不住代碼,或者不清楚其運行的流程,也許從 Systrace 這個圖形化的角度,你可以理解的更深入一些。

系列文章目錄

  1. Systrace 簡介
  2. Systrace 基礎知識 - Systrace 預備知識
  3. Systrace 基礎知識 - Why 60 fps ?
  4. Systrace 基礎知識 - SystemServer 解讀
  5. Systrace 基礎知識 - SurfaceFlinger 解讀
  6. Systrace 基礎知識 - Input 解讀
  7. Systrace 基礎知識 - Vsync 解讀
  8. Systrace 基礎知識 - Vsync-App :基於 Choreographer 的渲染機制詳解
  9. Systrace 基礎知識 - MainThread 和 RenderThread 解讀
  10. Systrace 基礎知識 - Binder 和鎖競爭解讀
  11. Systrace 基礎知識 - Triple Buffer 解讀
  12. Systrace 基礎知識 - CPU Info 解讀

正文

窗口動畫

Systrace 中的 SystemServer 一個比較重要的地方就是窗口動畫,由於窗口歸 SystemServer 來管,那麼窗口動畫也就是由 SystemServer 來進行統一的處理,其中涉及到兩個比較重要的線程,Android.Anim 和 Android.Anim.if 這兩個線程,這兩個線程的基本知識在下面有講。

這裏我們以應用啓動爲例,查看窗口時如何在兩個線程之間進行切換(Android P 裏面,應用的啓動動畫由 Launcher 和應用自己的第一幀組成,之前是在 SystemServer 裏面的,現在多任務的動畫爲了性能部分移到了 Launcher 去實現)

首先我們點擊圖標啓動應用的時候,由於 App 還在啓動,Launcher 首先啓動一個 StartingWindow,等 App 的第一幀繪製好了之後,再切換到 App 的窗口動畫

Launcher 動畫 Launcher 動畫

此時對應的,App 正在啓動 App 啓動

從上圖可以看到,應用第一幀已經準備好了,接下來看對應的 SystemServer ,可以看到應用啓動第一幀繪製完成後,動畫切換到 App 的 Window 動畫

Window 動畫
Window 動畫

ActivityManagerService

AMS 和 WMS 算是 SystemServer 中最繁忙的兩個 Service 了,與 AMS 相關的 Trace 一般會用 TRACE_TAG_ACTIVITY_MANAGER 這個 TAG,在 Systrace 中的名字是 ActivityManager

下面是啓動一個新的進程的時候,AMS 的輸出 AMS

在進程和四大組件的各種場景一般都會有對應的 Trace 點來記錄,比如大家熟悉的 ActivityStart、ActivityResume、activityStop 等,這些 Trace 點有一些在應用進程,有一些在 SystemServer 進程,所以大家在看 Activity 相關的代碼邏輯的時候,需要不斷在這兩個進程之間進行切換,這樣才能從一個整體的角度來看應用的狀態變化和 SystemServer 在其中起到的作用。 Trace 點

WindowManagerService

與 AMS 相關的 Trace 一般會用 TRACE_TAG_WINDOW_MANAGER 這個 TAG,在 Systrace 中 WindowManagerService 在 SystemServer 中多在 對應的 Binder 中出現,比如下面應用啓動的時候,relayoutWindow 的 Trace 輸出 WMS

在 Window 的各種場景一般都會有對應的 Trace 點來記錄,比如大家熟悉的 relayoutWIndow、performLayout、prepareToDisplay 等 WMS

Input

Input 是 SystemServer 線程裏面非常重要的一部分,主要是由 InputReader 和 InputDispatcher 這兩個 Native 線程組成,關於這一部分在 Systrace 基礎知識 - Input 解讀 裏面已經詳細講過,這裏就不再詳細講了

imput
imput

Binder

SystemServer 由於提供大量的基礎服務,所以進程間的通信非常繁忙,且大部分通信都是通過 Binder ,所以 Binder 在 SystemServer 中的作用非常關鍵,很多時候當後臺有大量的 App 存在的時候,SystemServer 就會由於 Binder 通信和鎖競爭,導致系統或者 App 卡頓。關於這一部分在 Binder 和鎖競爭解讀 裏面已經詳細講過,這裏就不再詳細講了 Binder

HandlerThread

BackgroundThread

com/android/internal/os/BackgroundThread.java

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

Systrace 中的 BackgroundThread BackgroundThread

BackgroundThread 在系統中使用比較多,許多對性能沒有要求的任務,一般都會放到 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 被使用的地方如下,具體的功能可以自己去源碼裏面查看,關鍵字是 UiThread.get() UiThread

IoThread

com/android/server/IoThread.java

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

IoThread 被使用的地方如下,具體的功能可以自己去源碼裏面查看,關鍵字是 IoThread.get() IoThread

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 + 1false /*allowIo*/);
}

Systrace 中的 DisplayThread DisplayThread

DisplayThread
DisplayThread

AnimationThread

com/android/server/AnimationThread.java

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

Systrace 中的 AnimationThread AnimationThread

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

AnimationThread 在源碼中的使用,可以看到 WindowAnimator 的動畫執行也是在 AnimationThread 線程中的,Android P 增加了一個 SurfaceAnimationThread 來分擔 AnimationThread 的部分工作,來提高 WindowAnimation 的動畫性能

AnimationThread
AnimationThread

FgThread

com/android/server/FgThread.java

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

Systrace 中的 FgThread 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

SurfaceAnimationThread 的名字叫 android.anim.lf , 與 android.anim 有區別, SurfaceAnimationThread

這個 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;
}

關於我 && 博客

  1. 關於我 , 非常希望和大家一起交流 , 共同進步 .
  2. 博客內容導航
  3. 優秀博客文章記錄 - Android 性能優化必知必會

一個人可以走的更快 , 一羣人可以走的更遠

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章