史上最全Android渲染机制讲解(长文源码深度剖析)

本文深入探讨Android的渲染机制,包括Vsync信号的协调、SurfaceFlinger的工作流程、应用程序的基本架构和可能导致滑动卡顿的原因。通过详细分析,揭示了Android如何保证UI流畅性和响应性,解答了关于渲染过程的关键问题。
摘要由CSDN通过智能技术生成

前言

渲染机制是Android操作系统很重要的一环,本系列通过介绍应用从启动到渲染的流程,揭秘Android渲染原理。

问题

1.vsync如何协调应用和SurfaceFlinger配合来完成UI渲染、显示,App接收vsync后要做哪些工作?
2.requestLayout和invalidate区别?
3.performTraversals到底是干什么了?
4.surfaceflinger怎么分发vsync信号的?
5.app需要主动请求vsync信号,sw sync才会分发给app?
6.surfaceview显示视频的时候,视频会一直频繁刷新界面,为什么整个UI界面没有卡顿?
7.app是如何构建起上面这套机制的?

如果对于上面的几个问题没有非常确认、清晰的答案可以继续看下去,本文通过详细介绍渲染机制解答上面的问题。

Vsync信号

Android在“黄油计划”中引入的一个重要机制就是:vsync,引入vsync本质上是要协调app生成UI数据和SurfaceFlinger合成图像,app是数据的生产者,surfaceflinger是数据的消费者,vsync引入避免Tearing现象。vsync信号有两个消费者,一个是app,一个是surfaceflinger,这两个消费者并不是同时接收vsync,而是他们之间有个offset。

vsync-offset引入原因

上面提到hw vsync信号在目前的Android系统中有两个receiver,App + SurfaceFlinger,hw sync会转化为sw sync分别分发给app和sf,分别称为vsync-app和vsync-sf。app和sf接收vsync会有一个offset,引入这个机制的原因是提升“跟手性”,也就是降低输入响应延。

如果app和sf同时接收hw sync,从上面可以看到需要经过vsync * 2的时间画面才能显示到屏幕,如果合理的规划app和sf接收vsync的时机,想像一下,如果vsync-sf比vsync-app延迟一定时间,如果这个时间安排合理达到如下效果就能降低延迟:

SufaceFlinger工作机制

组成架构

  1. EventControlThread: 控制硬件vsync的开关

  2. DispSyncThread: 软件产生vsync的线程

  3. SF EventThread: 该线程用于SurfaceFlinger接收vsync信号用于渲染

  4. App EventThread: 该线程用于接收vsync信号并且上报给App进程,App开始画图

  • HW vsync, 真实由硬件产生的vsync信号
  • SW vsync, 由DispSync产生的vsync信号
  • vsync-sf, SF接收到的vsync信号
  • vsync-app, App接收到的vsync信号

应用程序基本架构

Android应用进程核心组成

上图列举了Android应用进程侧的几个核心类,PhoneWindow的构建是一个非常重要的过程,应用启动显示的内容装载到其内部的mDecor,Activity(PhoneWindow)要能接收控制也需要mWindowManager发挥作用。ViewRootImpl是应用进程运转的发动机,可以看到ViewRootImpl内部包含mView、mSurface、Choregrapher,mView代表整个控件树,mSurfacce代表画布,应用的UI渲染会直接放到mSurface中,Choregorapher使得应用请求vsync信号,接收信号后开始渲染流程,下面介绍上图构建的流程。

应用启动流程图(下文称该图为P0)

进程启动

应用冷启动第一步就是要先创建进程,这跟linux类似C/C++程序是一致的,Android亦是通过fork来孵化应用进程,我们知道Linux fork的子进程继承父进程很多的资源,即所谓的COW。应用进程同样会从其父进程zygote处继承资源,比如art虚拟机实例、预加载的class/drawable资源等,以付出一些开机时间为代价,一来能够节省内存,二来能够加速应用性能,下面结合systrace介绍Android如何启动一个应用进程,应用启动第一个介入的管理者是AMS,应用启动过程中AMS发现没有process创建,就会请求zygote fork进程,下图就是AMS中创建进程的耗时:

AMS(ActivityManagerService)请求zygote创建进程的流程如下:

##ActvityManager:startProcessLocked

private final void startProcessLocked(ProcessRecord app, String hostingType,
  String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {

    boolean isActivityProcess = (entryPoint == null);
    if (entryPoint == null) entryPoint = "android.app.ActivityThread";
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +app.processName);
    checkTime(startTime, "startProcess: asking zygote to start proc");
    ProcessStartResult startResult;
    if (hostingType.equals("webview_service")) {
    startResult = startWebView(entryPoint,
      app.processName, uid, uid, gids, debugFlags, mountExternal,
            app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
      app.info.dataDir, null, entryPointArgs);
    } else {
        startResult = Process.start(entryPoint,
      app.processName, uid, uid, gids, debugFlags, mountExternal,
      app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
            app.info.dataDir, invokeWith, entryPointArgs);
  
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值