View绘制流程源码解析-第一篇

Android应用层View绘制流程与源码分析,墙都不扶就服你 通过上面分析可以看出measure过程主要就是从顶层父View向子View递归调用view.measure方法(measure中又回调onMeasure方法)的过程。 阅读详情

绘制流程概览

Android程序启动 -> Activity加载并调用生命周期onCreate -> Activity调用setContentView -> UI绘制

Android启动流程分析

我们都知道Android程序的启动入口是ActivityThread.main函数,那么看一看main函数是如何进行启动的。

ActivityThread.class

public static void main(String[] args) {
   …
    ActivityThread thread = new ActivityThread();
    thread.attach(false);
    …
}
private void attach(boolean system) {
  	…
        final IActivityManager mgr = ActivityManager.getService();
        try {
            mgr.attachApplication(mAppThread);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
	…
}

由上面的源码可知,我们在main函数中做了两件事情:

  • 生成一个ActivityThread对象
  • 调用该对象的attach方法

在attach方法中,也做了两件事情:

  • 获取了IActivityManager的对象实例
  • 执行该对象的attachApplication方法

通过ActivityManager.getService()获取到Activity管理器接口对象,那么如何拿到的呢?我们来看下源码实现:

ActivityManager.class

/**
 * @hide
 */
public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
}

private static final Singleton<IActivityManager> IActivityManagerSingleton =
        new Singleton<IActivityManager>() {
            @Override
            protected IActivityManager create() {
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                final IActivityManager am = IActivityManager.Stub.asInterface(b);
                return am;
            }
        };

  • 服务管理器通过getService拿到了ActivityService 的IBinder对象,通过跨进程获取到am对象。
  • mgr.attachApplication(mAppThread)是将ApplicationThread和ActivityManagertService相关联。

在APP进程启动之后,AMS便会跨binder调用到ApplicationThread的scheduleLaunchActivity,启动Activity。
详细的介绍请参照深入理解Activity——Token之旅

通过上面的分析,我们知道ApplicationThread这个对象在启动过程中起着至关重要的作用,来看下它的源码:
ApplicationThread类里面都干了什么事情?

ApplicationThread.class

private class ApplicationThread extends IApplicationThread.Stub {
  public final void schedulePauseActivity(IBinder token, boolean finished, ...
  public final void scheduleStopActivity(IBinder token, boolean showWindow, ...
   @Override public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ...
...

如上图所示,一堆的schedule方法,按照字面翻译,我们可以猜测出,这个是在Activity状态变化时去调用的方法。
在诸多的schedule方法里面,根据注释得知,scheduleLaunchActivity是在Activity加载的时候调用,我们来看一下:

ApplicationThread.class

        // we use token to identify this activity without having to send the
        // activity itself back to the activity manager. (matters more with ipc)
        @Override
        public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
                int procState, Bundle state, PersistableBundle persistentState,
                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

            updateProcessState(procState, false);

            ActivityClientRecord r = new ActivityClientRecord();

         ...
            updatePendingConfiguration(curConfig);

            sendMessage(H.LAUNCH_ACTIVITY, r);
        }

根据代码我们可以分析

  • 创建了ActivityClientRecord对象
  • 将ActivityClientRecord对象以及标志位LAUNCH_ACTIVITY发送出去

ApplicationThread.class

private void sendMessage(int what, Object obj) {
        sendMessage(what, obj, 0, 0, false);
    }
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        if (DEBUG_MESSAGES) Slog.v(
            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
            + ": " + arg1 + " / " + obj);
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);
    }

final H mH = new H();

private class H extends Handler {
...
}

通过以上代码可以知道,将创建的ActivityClientRecord对象以及标志位通过handler发送出去,那我们顺着找到mH的handleMessage方法

private class H extends Handler {
...
public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case LAUNCH_ACTIVITY: {
                  ...
                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
                  ...
                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                   ...
                } break;
                   ...
            }
          ...
        }
 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
  ...
             Activity a = performLaunchActivity(r, customIntent);
  ...
}

 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
  ...
             if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
             } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
             }
  ...
}

对应着LAUNCH_ACTIVITY,调用到了handleLaunchActivity函数-> performLaunchActivity函数,在performLaunchActivity函数中,我们可以看到 mInstrumentation.callActivityOnCreate的字样,猜的没错的话,这就是调用Activity的onCreate函数的入口了,我们看下源码:

Instrumentation.class

 /**
     * Perform calling of an activity's {@link Activity#onCreate}
     * method.  The default implementation simply calls through to that method.
     *  @param activity The activity being created.
     * @param icicle The previously frozen state (or null) to pass through to
     * @param persistentState The previously persisted state (or null)
     */
    public void callActivityOnCreate(Activity activity, Bundle icicle,
            PersistableBundle persistentState) {
        prePerformCreate(activity);
        activity.performCreate(icicle, persistentState);
        postPerformCreate(activity);
    }

Activity.class

  final void performCreate(Bundle icicle) {
        performCreate(icicle, null);
    }

    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
      ...
        if (persistentState != null) {
            onCreate(icicle, persistentState);
        } else {
            onCreate(icicle);
        }
      ...
    }
public void onCreate(@Nullable Bundle savedInstanceState,
            @Nullable PersistableBundle persistentState) {
        onCreate(savedInstanceState);
    }

总结一下调用关系,Instrumentation. callActivityOnCreate-> Activity. performCreate->Activity.onCreate。
到此为止,我们的整个APP已经成功启动啦~
总结一下:
APP启动到调用Activity.create函数调用总结.png

2.Activity调用setContentView做了什么?
敬请期待

Activity 启动流程至view绘制到屏幕显示 Activity 启动 至 view绘制 至 屏幕显示 实际效果:Activity冷启动的时候会闪黑屏,就是A启动B,这个过程中会闪黑屏,虽然网上说可以设置一个闪屏页,中间有个过渡效果,或者设置B为透明主题,这样在启动的时候就看不到黑屏了。只是感觉启动B的这个过程漫长而已,又比如说你从桌面启动A,你把A设为透明,你就会感觉你点击A之后半天没反应没启动起来,实际是有反应的哇,因为你设置的透明,所以... 阅读详情

相关推荐

Android View绘制及事件(三)自定义View及View绘制流程

前言 一、自定义View介绍 二、View绘制流程 2.1Measure() 2.2 Layout() 2.2 Draw() 注意 前言 我们经常使用TextView、button等控件,但是有些同学对于它们是如何显示和扩展的却并不那么熟悉。而这一块的知识也进阶高手必备的,写这一篇文章是想把view绘制这块的技术全面总结一下。 Activity作为应用程序的载体负责向用...

csdn_aiyang的博客 2266

View绘制流程分析

想要弄清楚View是怎么绘制的得先弄明白View是怎么创建出来的。我们先来看下View的创建流程。总结如下所示:Activity执行onResume之后再ActivityThread中执行Activity的makeVisible方法。View的绘制流程包含了测量大小,测量位置,绘制三个流程;Activity的界面绘制是从mDoctor即根View开始的,也就是从mDoctor的测量大小,测量位置,绘制三个流程;

杨充 1289

从零开始:用AutoLisp为AutoCAD定制专属工具栏(2023最新版)

本文详细介绍了如何利用AutoLisp语言为AutoCAD定制专属工具栏,以提升绘图效率。内容涵盖从环境配置、AutoLisp基础语法到实战开发的全过程,指导用户编写自动化脚本、封装功能函数,并最终通过CUI编辑器创建和部署个性化工具栏按钮,是2023年CAD用户实现工作流自动化与个性化的实用指南。

4k5l6j7h8的博客 299

从源码解析-Android中View的绘制流程及performTraversals方法

谈谈Activity的setContentView是怎么加载XML视图的 谈谈Activity的View怎么与View绘制工具ViewRootImpl关联的 在前面两篇文章中分析了View是如何跟绘制工具ViewRootImpl关联的,setContentView是如何把我们编写的xml视图添加到Activity中的,那今天就要分析下绘制工具ViewRootImpl是如何绘制我们Activit...

Mango先生的博客 4965

sdc时钟约束2——多驱动时钟

sdc 多驱动时钟 master_clock

qq_40411444的博客 5527

anaconda安装-超详细版

文章目录一、anaconda安装1.1 anaconda安装地址1.2 安装详细步骤检验安装是否成功更改conda源(后续安装第三方库可以加快速度) 一、anaconda安装 Anaconda 是一个用于科学计算的 Python 发行版,支持 Linux, Mac, Windows, 包含了众多流行的科学计算、数据分析的 Python 包。装anaconda,就不需要单独装python了。 anaconda优点: 1、anaconda里面集成了很多关于python科学计算的第三方库,主要是安装方便,而p

in546的博客 25万+

Android应用层View绘制流程与源码分析

【工匠若水 http://blog.youkuaiyun.com/yanbober 转载烦请注明出处,尊重分享成果】1 背景还记得前面《Android应用setContentView与LayoutInflater加载解析机制源码分析》这篇文章吗?我们有分析到Activity中界面加载显示的基本流程原理,记不记得最终分析结果就是下面的关系:看见没有,如上图中id为content的内容就是整个View树的结构,所

工匠若水 14万+

小白快速上手 labelme:新手图像标注详解教程

本教程旨在帮助初次接触 labelme 的用户快速上手该软件,掌握基本操作与标注流程,为语义分割数据集做准备。

小白一枚~ 2万+

Android View绘制流程(源码分析)

这里写目录标题一 前言二 View绘制2.1 View绘制的三个流程2.2 Android视图层次结构简介三 View绘制流程3.1 DecorView的创建(setContentView)3.2 顶层视图DecorView添加到窗口的过程3.3 ViewRootImpl(DecorView与window沟通的桥梁)3.3.1 执行流程3.4 measure过程分析3.4.1 MeasureSpec**和**ViewGroup.LayoutParams**类3.4.2 View测量的基本流程及重要方法分析3

qq_39431405的博客 1115

Java 部分笔试题解析

合法的 try 语句块必须包含 try 块,并且至少包含一个 catch 块或一个 finally 块。给定一个长度为n的数组,数组中的每个元素,表示一根水管的长度,水管可以在任意位置锯开。调用 sleep() 方法、创建新线程、高优先级线程进入就绪状态只会暂停或抢占线程的执行,而不会终止线程的运行。A.抽象类中可以包含非抽象的普通方法,接口中的方法必须是抽象的,不能有非抽象的普通方法。接口中的成员变量必须是常量(static final),而抽象类可以有普通成员变量。

博客 2578

危废焚烧优化控制系统设计与实现:基于数据驱动的控制参数预测

本文提出了一种基于数据驱动的危险废物焚烧过程优化控制方法。系统利用历史运行数据和实时监测数据,通过深度学习模型预测关键控制参数,实现焚烧过程的智能化控制。系统采用Python开发,结合TensorFlow/PyTorch框架,构建了完整的数据采集、预处理、特征工程、模型训练和实时预测闭环系统。该系统能够处理多变量非线性关系,适应工况变化,从历史数据中学习最优控制策略,相比传统PID控制方法具有显著优势。论文详细介绍了系统架构、算法设计和实现细节,为危废焚烧过程的优化控制提供了有效解决方案。

huanghm88的专栏 206

深入解析View的绘制源码流程

View的绘制流程 今天来讲讲View的绘制流程吧,这一块也是我比较薄弱的地方,而且之前没有什么耐心去看这一块。今天就来学习这一块的知识点。主要分为3部分: View树的创建 ViewRootImpl的创建 真正的绘制流程开始performTraversals View树的创建 首先思考一个问题View的绘制从那里开始?关于这个问题我一开始也谷歌百度了很多东西,但是还是不能解决我的疑惑。所以今天我打算从根本上解决这个问题——从Activity的setContentView开始看。下面开始我的

weixin_37873786的博客 882

Calibre:LVS 快速debug short/open技巧

用Fix Suggestion和Short Isolate两种方法debug LVS问题

m0_61544122的博客 7455

Android View原理解析之绘制流程(draw)

自定义View是Android进阶路线上必须攻克的难题,而在这之前就应该先对View的工作原理有一个系统的理解。本系列将分为4篇博客进行讲解,本文主要对View的绘制流程(draw)进行讲解。

CodingEnding的博客 1457

DataX对接数据如何在ODS加密脱敏数据(插件开发)

datax对接mysql数据,对姓名只保留姓,名变成**。对这种简单的脱敏,可以不用修改datax源码,直接在配置文件上实现。

大模型大数据攻城狮的专栏 993

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Android中View的绘制流程

一、 摘要 介绍Android View的绘制流程,引出后续的异步消息、事件分发。 二、 ViewRootImpl 1. ViewRootImpl是什么 在API文档中如此描述ViewRootImpl: /** * The top of a view hierarchy, implementing the needed protocol between View * and the Wind...

进击的小宇宙 4682

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

从invalidate分析view绘制流程

1.前言 关于view的绘制流程,现在网上一查,就会直接告诉你,view的绘制流程是先onMeasure,然后onLayout,在最后onDraw,没错,绘制流程确实也是这样。所以我们今天要讨论的话题除了那三大方法内部到底做了什么,还要知道这个流程是怎么来的。这样大家就会对view的绘制过程有一个比较清晰的认识。 这里我想从view的一些常用方法来进行研究,就从invalidate这个方法开始吧。...

你缺少想象力的博客 4113

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

开源项目源码解析-View 绘制流程

View 绘制流程 本文为 Android 开源项目源码解析 公共技术点中的 View 绘制流程 部分 分析者:lightSky View 绘制机制 1. View 树的绘图流程 当 Activity 接收到焦点的时候,它会被请求绘制布局,该请求由Android framework 处理.绘制是从根节点开始,对布局树进行 measure 和 draw 。整个 View 树的绘图

第四维空间的专栏 940

一文彻底搞懂Android View的绘制流程

我们都知道,PhoneWindow是Android系统中最基本的窗口系统,每个Activity会创建一个。同时,PhoneWindow也是Activity和View系统交互的接口。DecorView本质上是一个FrameLayout,是Activity中所有View的祖先...

IT元老的博客 6128

Android View的绘制流程

Android View的绘制三大流程 View的mesure、layout、draw三大流程。本文将详细讲解View的三大流程,阅读本文最好有牢固的Android基础,并且对Android View的基本结构有所了解。View的三大流程非常的重要,感觉现在面试必问。 同时,这个流程熟悉对于提升我们的开发水平也有很大的帮助。 在实际的开发中解决那种坑逼的问题时,熟悉三大流程必将事倍功半。 本文...

samuelnotes的专栏 4989

View绘制流程源码解析

1 View能在子线程更新吗 1 View绘制流程的主要对象 2 View绘制流程的函数调用

Vincent的博客 807

Android视图绘制流程完全解析,带你一步步深入了解View(二)

在上一篇文章中,我带着大家一起剖析了一下LayoutInflater的工作原理,可以算是对View进行深入了解的第一步吧。那么本篇文章中,我们将继续对View进行深入探究,看一看它的绘制流程到底是什么样的。如果你还没有看过我的上一篇文章,可以先去阅读 Android LayoutInflater原理分析,带你一步步深入了解View(一) 。 相信每个Android程序员都知道,我们每天的开发工作当中都在不停地跟View打交道,Android中的任何一个布局、任何一个控件其实都是直接或间接继承自View的,

郭霖的专栏 24万+

再谈Android View绘制流程

笔者在这里提醒读者,Android的View是UI的高级抽象,我们平时使用的XML文件也好,本质是设计模式中的一种策略模式,其View可以理解为一种底层UI显示的Request。各种VIew的排布,来自于开发者编写的XML文件,或动态增添删除View,这一系列的集合即一种策略。而这种策略最终会被Android系统解析为一种Request请求。什么意思呢?就是应用进程在此充当绘制的客户端,而服务器是谁?记住,即便屏幕前是我们所描绘的某种策略绘制的UI,那也是Surface系统服务器的Response表现。

qq_40900926的博客 1525

谈谈 View 绘制流程

注:本文使用 sdk 23 作为源码参考。 前言 ViewRootImpl#performTraversals() ViewRootImpl#performMeasure() ViewRootImpl#performLayout() ViewRootImpl#performDraw() some tips onDraw() dispatchDraw() 前言 关于 View 的绘制流

joker 878

Android源码分析之View的绘制流程

Android View的绘制流程详解(包括View的来龙去脉) 对于Android开发者来说,View无疑是开发中经常接触的,包括它的事件分发机制、测量、布局、绘制流程等,如果要自定义一个View,那么应该对以上流程有所了解、研究。本系列文章将会为大家带来View的工作流程详细解析。在深入接触View的测量、布局、绘制这三个流程之前,我们从Activity入手,看看从Activity创建后到V...

博由心生,福泽一生 1477

从源码的角度分析View的绘制流程

温馨提示:以下源码分析会截取源码进行说明,部分方法源码较长会只保留关键代码,其他代码用…省略 View的绘制入口是ActivityThread#handleResumeActivity final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean re...

isJoker的博客 255
上一篇: Handler源码解析系列一
下一篇: 剑指Offer数组习题-合并两个有序数组
丸子哒哒哒
博客等级 码龄12年 31粉丝 50原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值