Android view 工作流程《上》

戏说Android view 工作流程《下》 遍历View树performTraversals()执行过程 view树遍历概述 还是回到ViewRoot.java,我们直接看performTraversals(),该函数就是android系统View树遍历工作的核心。一眼看去,发现这个函数挺长的,但是逻辑是非常清晰的,其执行过程可简单概括为根据之前所有设置好的状态,判断是否需要计算视图大小(measure)、是否需要重新安置视 阅读详情

view基本认识

回想你第一次看到Android设备时,上面各种酷炫的应用和游戏是不是让多年使用塞班手机的你感到amazing?能看到这篇文章说明你现在的工作多少和android开发相关。或许你是跟着教程写了一个HelloWold运行在模拟器或者真机上,结果出来的瞬间会有些自豪。心想着自己也是会android应用开发的人了。

接着可能陆陆续续的写了几个小Demo,这时候对android应用的印象多了四大组件等一些概念,提到view,你可能会说,视图不就是窗口,而一个窗口往往就是一个activity。所以会有一个activity就是一个view的错觉。其实也不能说完全错了,这其中确实有玄机。

setContentView说起

为啥会让我们有activity即view的印象,原因就在于Activity一般都在onCreate函数中里使用setContentView设置UI界面。我们略作分析:

mWindow为何物?

Activity.java

  

[java]  view plain copy
  1.  /** 
  2.      * 根据布局文件来填充activity的view。 
  3.      */  
  4.     public void setContentView(int layoutResID) {  
  5.         getWindow().setContentView(layoutResID);//我们需要看下getWindow()返回的是什么。  
  6. }  
  7. /** 
  8.      * Retrieve the current {@link android.view.Window} for the activity. 
  9.      * This can be used to directly access parts of the Window API that 
  10.      * are not available through Activity/Screen. 
  11.      *  
  12.      * @return Window The current window, or null if the activity is not 
  13.      *         visual. 
  14.      */  
  15.     public Window getWindow() {  
  16.         return mWindow;// 是window的一个实例  
  17.     }  

mWindow是何方神圣,又是谁创造了它,我们control+F一下在attach函数中找到了它mWindow =PolicyManager.makeNewWindow(this),不过又多出来一个PolicyManager,这货又是干啥的,我们进去看看先。

[java]  view plain copy
  1. public final class PolicyManager {  
  2.     private static final String POLICY_IMPL_CLASS_NAME =  
  3.         "com.android.internal.policy.impl.Policy";  
  4.   
  5.     private static final IPolicy sPolicy;  
  6.   
  7.     static {  
  8.         // Pull in the actual implementation of the policy at run-time  
  9.         try {  
  10.             Class policyClass = Class.forName(POLICY_IMPL_CLASS_NAME);  
  11.             sPolicy = (IPolicy)policyClass.newInstance();  
  12.         } catch (ClassNotFoundException ex) {  
  13.             throw new RuntimeException(  
  14.                     POLICY_IMPL_CLASS_NAME + " could not be loaded", ex);  
  15. 。。。。。。  
  16. // The static methods to spawn new policy-specific objects  
  17.     public static Window makeNewWindow(Context context) {  
  18.         return sPolicy.makeNewWindow(context);  
  19.     }  
  20. }  


该类代码比较少,申明了一个Policy类型的单例对象,我们再看看它是神马。

[java]  view plain copy
  1. public PhoneWindow makeNewWindow(Context context) {  
  2.         return new PhoneWindow(context);//亲,注意啦,出现关键词PhoneWindow。  
  3. }  

到这里我们弄清楚了一个事实,mWindow就是一个PhoneWindow对象。同样的手法,我们可以知道mWindowManager成员变量的真实类型是LocalWindowManager。

深入setContentView

弄清楚了以上概念,我们可以重新回到setContenView函数了。根据上面的结论,直接到PhoneWindow去找它。

  

[java]  view plain copy
  1. public void setContentView(View view, ViewGroup.LayoutParams params) {  
  2.        if (mContentParent == null) {  
  3.            installDecor();  
  4.        } else {  
  5.            mContentParent.removeAllViews();  
  6.        }  
  7.        mContentParent.addView(view, params);  
  8.        final Callback cb = getCallback();  
  9.        if (cb != null) {  
  10.            cb.onContentChanged();  
  11.        }  
  12.    }  

可以知道mContentParent是viewGroup类型,它存在时就负责把view加载出来,不存在的时候会走installDecor方法。

    

[java]  view plain copy
  1.  private void installDecor() {  
  2.         if (mDecor == null) {  
  3.             mDecor = generateDecor();//创建mDecor,它是DecorView类型,继承于FrameLayout。  
  4.             mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);  
  5.             mDecor.setIsRootNamespace(true);  
  6.         }  
  7.         if (mContentParent == null) {  
  8.             mContentParent = generateLayout(mDecor);  
  9.             //创建标题栏  
  10.             mTitleView = (TextView)findViewById(com.android.internal.R.id.title);  
  11.           ......  
  12.         }  
  13. }  

这里需要我们进一步看下generateDecor()方法:

[java]  view plain copy
  1. protected ViewGroup generateLayout(DecorView decor) {  
  2.         // Apply data from current theme.  
  3. //1,根据getWindowStyle()返回的数组来设定一些窗口属性值feature,如是否全屏,是否带标题栏。  
  4.         TypedArray a = getWindowStyle();  
  5.         mIsFloating = a.getBoolean(com.android.internal.R.styleable.Window_windowIsFloating, false);  
  6.         int flagsToUpdate = (FLAG_LAYOUT_IN_SCREEN|FLAG_LAYOUT_INSET_DECOR)  
  7.                 & (~getForcedWindowFlags());  
  8.         if (mIsFloating) {  
  9.             setLayout(WRAP_CONTENT, WRAP_CONTENT);  
  10.             setFlags(0, flagsToUpdate);  
  11.         } else {  
  12.             setFlags(FLAG_LAYOUT_IN_SCREEN|FLAG_LAYOUT_INSET_DECOR, flagsToUpdate);  
  13.         }  
  14.   
  15.         if (a.getBoolean(com.android.internal.R.styleable.Window_windowNoTitle, false)) {  
  16.             requestFeature(FEATURE_NO_TITLE);  
  17.         }  
  18.   
  19.         if (a.getBoolean(com.android.internal.R.styleable.Window_windowFullscreen, false)) {  
  20.             setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN&(~getForcedWindowFlags()));  
  21.         }  
  22.   
  23.         if (a.getBoolean(com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {  
  24.             setFlags(FLAG_SHOW_WALLPAPER, FLAG_SHOW_WALLPAPER&(~getForcedWindowFlags()));  
  25.         }  
  26.         ......  
  27.         // Inflate the window decor.  
  28. //2,根据上面设定的features值,决定加载何种窗口布局文件。  
  29.         int layoutResource;  
  30.         int features = getLocalFeatures();  
  31.         // System.out.println("Features: 0x" + Integer.toHexString(features));  
  32.         if ((features & ((1 << FEATURE_LEFT_ICON) | (1 << FEATURE_RIGHT_ICON))) != 0) {  
  33.             if (mIsFloating) {  
  34.                 layoutResource = com.android.internal.R.layout.dialog_title_icons;  
  35.             } else {  
  36.                 layoutResource = com.android.internal.R.layout.screen_title_icons;  
  37.             }  
  38.         ......  
  39.         }  
  40.         mDecor.startChanging();  
  41. //3,把特定的view添加到decorView里。  
  42.         View in = mLayoutInflater.inflate(layoutResource, null);  
  43.         decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));  
  44. //4,这个contentParent由findViewById返回,实际上就是mDecorView一部分。  
  45.         ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);  
  46.         ......  
  47.         mDecor.finishChanging();  
  48.         return contentParent;  
  49. }  

窗口布局文件解析

上面第二步提到根据上面设定的features值,决定加载何种窗口布局文件,我们找一个系统窗口布局文件分析一下:

路径在:.frameworks/base/core/res/layout/screen_title.xml 

[java]  view plain copy
  1. <!--  
  2. This is an optimized layout for a screen, with the minimum set of features  
  3. enabled.  
  4. -->  
  5.   
  6. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  7.     android:orientation="vertical"  
  8.     android:fitsSystemWindows="true">  
  9.     <FrameLayout  
  10.         android:layout_width="match_parent"   
  11.         android:layout_height="?android:attr/windowTitleSize"  
  12.         style="?android:attr/windowTitleBackgroundStyle">  
  13.         <TextView android:id="@android:id/title"   
  14.             style="?android:attr/windowTitleStyle"  
  15.             android:background="@null"  
  16.             android:fadingEdge="horizontal"  
  17.             android:gravity="center_vertical"  
  18.             android:layout_width="match_parent"  
  19.             android:layout_height="match_parent" />  
  20.     </FrameLayout>  
  21.     <FrameLayout android:id="@android:id/content"  
  22.         android:layout_width="match_parent"   
  23.         android:layout_height="0dip"  
  24.         android:layout_weight="1"  
  25.         android:foregroundGravity="fill_horizontal|top"  
  26.         android:foreground="?android:attr/windowContentOverlay" />  
  27. </LinearLayout>  

 可以看到是一个简单的布局文件,一个LinearLayout下包含了两个子FrameLayout视图,第一个FrameLayout用来显示标题栏(TitleBar);第二个FrameLayout用来显示id为content视图。

穿越回顾一下view结构


以上我们由setcontentView()引出了两个在view界举足轻重的大佬PhoneWindow和DecorView,它们之间的关系可以简单用下面的图来表示。

        

总结

举个不太恰当的类比:如果说PhoneWindow是画,一种抽象概念的画,那DecorView会更具体一点,它可以是山水画。而MyView就是具体的唐伯虎手下的凤凰傲意图了。

这里说的View、DecorView等都是UI单元,这些UI单元工作都在onDraw函数中完成。如果把onDraw想象成画图过程,那我们需要知道画布是什么?查阅资料后,得出答案就是Surface,关于它的前世今生还需看一下源码ViewRoot.java。

[java]  view plain copy
  1. public final class ViewRoot extends Handler implements ViewParent,  
  2.         View.AttachInfo.Callbacks {  
  3.     View mView;  
  4. private final Surface mSurface = new Surface();  
  5.  }  

以上我们收集齐了PhoneWindow,DecorView,ViewRoot,Surface四颗神奇的龙珠,让我们一起把view召唤到手机屏幕上吧。

家庭网络中,路由器和交换机的连接顺序 它的目的是给路由器增加端口,用户访问互联网的速度比情况一要快,常用于办公网络、家庭成员多的场景。光纤入户首先连接的肯定是光猫,而在光猫的后面,是先连接交换机?还是应该接路由器呢?家庭网络中路由器和交换机的先后连接顺序。它目的是让更多的用户访问互联网。常用于一些超大型机房、网吧等。至于路由器和交换机的区别。两者之间很多功能都有兼容。但用户上网速度相对较慢。在技术日益迭代的今天。 阅读详情

相关推荐

数仓项目6.0(一)

数据同步工具种类繁多,大致可分为两类,一类是以DataX、Sqoop为代表的基于Select查询的离线、批量同步工具,另一类是以Maxwell、Canal为代表的基于数据库数据变更日志(例如MySQL的binlog,其会实时记录所有的insert、update以及delete操作)的实时流式同步工具。DataX的使用,用户只需根据数据的数据源和目的地选择相应的Reader和Writer,并将Reader和Writer的信息配置在一个json文件中,然后执行如下命令提交数据同步任务即可。

qq_58551342的博客 2849

戏说Android view 工作流程《上》

view基本认识 回想你第一次看到Android设备时,上面各种酷炫的应用和游戏是不是让多年使用塞班手机的你感到amazing?能看到这篇文章说明你现在的工作多少和android开发相关。或许你是跟着教程写了一个HelloWold运行在模拟器或者真机上,结果出来的瞬间会有些自豪。心想着自己也是会android应用开发的人了。 接着可能陆陆续续的写了几个小Demo,这时候对android...

daibalusu 191

【新手必看】挖漏洞流程指南,黑客手把手教你挖漏洞月入过万!收藏这篇就够了!(附学习笔记)

【新手必看】挖漏洞流程指南,黑客手把手教你挖漏洞月入过万!收藏这篇就够了!(附学习笔记)【新手必看】挖漏洞流程指南,黑客手把手教你挖漏洞月入过万!收藏这篇就够了!(附学习笔记)

weixin_57514792的博客 1105

Android高级UI开发(三十三)android setContentView布局加载流程(一) 布局结构

想必大家都写过Activity中onCreate函数里的setContentView(R.layout.main);这行代码吧。 这行代码是如何将我们的布局显示到Activity里的?今天就带大家来解析一番。 首先,我们进入到Activity的setContentView函数里,代码如下: /** * Set the activity content from a layout resou...

gaoxiaoweiandy的专栏 2229

51单片机也能玩转GC9A01彩屏?超详细移植指南与性能优化技巧

本文详细介绍了如何在51单片机上高效驱动GC9A01彩屏,包括硬件连接优化、SPI模拟驱动、内存管理策略及高级刷新技术。通过分段缓冲、颜色压缩和差异化刷新等技巧,显著提升显示性能,使51单片机也能流畅运行240x240分辨率的彩色TFT屏幕。

hp777的博客 190

CarPlay wired(USB)连接方案

CarPlay的wired(USB)的连接方案要求车载设备至少要支持USB2.0 Hi-Speed,支持USB Host Mode,该模式要求车载设备能够工作在USB device模式下,因为Apple设备在CarPlay中是作为USB Host的。而通常情况下,车载设备USB是工作在USB Host模式的,而外接的USB设备是工作在USB Device模式的,因而在这种情况下的CarPlay wired(USB)连接方案中就需要进行USB的模式切换。模式切换完成后便是Apple设备(USB HOST)的枚

Ke8323的博客 1万+

Android setContentView源码解析

从入门应用Hello World 说起,我们简单的用setContentView设置了一个布局,然后启动我们的应用,手机界面就显示出Hello World的布局,这个背后到底发生了什么,这就是我今天所研究的对象。 首先弄清楚几个跟View有关的概念

小码农大梦想 766

京东联盟API实战:5分钟搞定商品返利链接生成(附Python代码)

本文详细介绍了如何利用京东联盟API快速构建自动化商品返利链接生成系统。通过Python代码实战,从API申请、环境配置到核心功能封装,手把手教你实现批量商品信息查询与推广链接生成,帮助内容创作者和开发者大幅提升电商推广效率。

weixin_29216957的博客 674

Android 之修改标题栏(title)

1、首先导入ActionBarActivity包,然后将MainActivity继承Activity而不是ActionBarActivity(注意这里只改变的了主界面的标题) import android.support.v7.app.ActionBarActivity; public class MainActivity extends Activity //不然会出现异常 2、在M

catchingSun的专栏 2万+

Oracle EBS Interface/API(29) - AP发票API

续上编文章《Oracle EBS Interface/API(28) - 客制化开发AP付款API》背景,介绍如调用官方提供标准AP发票API调用 用户界面 Invoices(Payables Manager->Invoices->Entry->Invoices) Open Interface Invoices(Payables Manager->Invoices->Entry->Open Interface Invoices) 快速参考 参考点 内容.

陈显平的专栏-Oracle EBS 1151

【CanMV K210】AI 视觉 MNIST 手写数字识别与分类推理

本文介绍了基于CanMV K210开发板的MNIST手写数字识别实验。实验通过摄像头采集图像,经过开窗、灰度化、缩放、反色等预处理后,使用KPU神经网络加速器运行MNIST分类模型,最终在LCD上显示识别结果。重点讲解了分类模型与检测模型的区别、图像预处理流程以及KPU推理结果的解析方法。实验帮助理解从图像采集到分类输出的完整AI视觉处理链路,并提供了调试思路和硬件连接说明。

Mr数据杨 366

【Android】View的工作流程——measure

看到这里你对Activity的构成有一定的了解,每个Activity都有一个与之关联的Window对象,而DecorView是这个Window的根视图。当DecorView被创建以及加载资源的时候,此时它的内容还无法进行显示,因为还没有加载到Window当中。接下来就看看是如何加载的。DecorViewWindow当我们调用Activity的方法的时候,最终调用的是的方法来创建上面的方法是用来创建Activity,里面会调用Activity的onCreate我们看到会调用方法最终调用到了Activity的。

2301_79828182的博客 1607

康耐视visionpro-CogCreateSegmentAvgSegsTool操作工具详细说明

康耐视visionpro-CogCreateSegmentAvgSegsTool操作工具详细说明

视觉人机器视觉的博客 1481

安卓View工作流程

前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。 提示:以下是本篇文章正文内容,下面案例可供参考 一、pandas是什么? 示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。 二、使用步骤 1.引入库 代码如下(示例): import numpy as np import pandas as pd import matplotli..

bugmaker的博客 564

OV9734 DATASHEET,完整规格书

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

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

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

【Android】View的工作流程

measure流程分为View的measure流程和ViewGroup的measure流程。其中,ViewGroup的measure流程除完成自身测量外,还需遍历调用子元素的measure()方法。

2303_79296612的博客 1073

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

安卓入门四十六 View工作流程

从上面的performTraversals()可知:View的绘制流程从顶级View(DecorView)的ViewGroup开始,一层一层从ViewGroup至子View遍历测绘。在Activity中通过 setContentView()所设置的布局文件其实是被加到内容栏之中的,成为其唯一子View = id为content的FrameLayout中。即:自上而下遍历、由父视图到子视图、每一个 ViewGroup 负责测绘它所有的子视图,而最底层的 View 会负责测绘自身。计算视图(View)的位置。

weixin_52735932的博客 618

安卓复习之旅—View的工作流程1

本篇文章主要是回顾一下安卓中view的工作原流程,view的工作流程主要包含measure、layout和draw三大流程,在进入主题之前,先要理解一下几个概念,以便更好的理解view的三大流程;了解ViewRoot和DecorView ViewRoot对应ViewRootImpl类,实现了ViewParent接口,它是连接WindowManager和DecorView的桥梁,WindowMana

lin_t_s的博客 953

android activity怎么调用非activity类_Android视图体系—View的工作流程

Android中View体系概览在Android应用中所有的用户界面元素都是由View和ViewGroup对象构建而成。View对象用于绘制屏幕中可以和用户交互的内容。ViewGroup用于存储其他View对象和ViewGroup对象,从而构成界面的布局。就如图中所示,用户界面的布局就是通过View和ViewGroup的结构层次定义的。View和ViewGroup组成了用户界面的View树,在Vi...

weixin_42538752的博客 203

android的构成和工作流程,分析Android中View的工作流程

8种机械键盘轴体对比本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?在分析View的工作流程时,需要先分析一个很重要的类,MeasureSpec。这个类在View的测量(Measure)过程中会用到。MeasureSpecMeasureSpec是View的静态内部类,可以理解为是一种测量规格,是一个32位int值,高2位代表SpecMode,低30位代表SpecSize,SpecMode...

weixin_31272749的博客 129

android activity根节点addview_Android视图体系—View的工作流程

Android中View体系概览在Android应用中所有的用户界面元素都是由View和ViewGroup对象构建而成。View对象用于绘制屏幕中可以和用户交互的内容。ViewGroup用于存储其他View对象和ViewGroup对象,从而构成界面的布局。就如图中所示,用户界面的布局就是通过View和ViewGroup的结构层次定义的。View和ViewGroup组成了用户界面的View树,在Vi...

weixin_39548805的博客 376

Android View的工作流程

View的工作流程View的measure过程View的measure过程由measure方法来完成,其中会调用onMeasure方法来确定View的大小。一般来说,继承View的子类都会重写onMeasure方法来确定大小。首先,看看View的onMeasure方法。protected void onMeasure(int widthMeasureSpec, int heightMeasureSp

ws_lm的博客 422

Android View的工作流程总结分析 (一) -performTraversals

Android View的工作流程      Android View的工作流程主要有三大流程:    measure 流程,测量获得View所需要的宽高    layout 流程,布局决定View在屏幕中具体的位置(决定实际的宽高)    draw 流程 绘制,真正将View的内容显示到匹配中    View工作是从什么地方开始的呢?先说结论:ViewRootImpl调用per

limushan的博客 1215

android wms 管理view的流程,Android View的工作流程

//ViewRootImplprivatevoidperformLayout(WindowManager.LayoutParams lp, intdesiredWindowWidth,intdesiredWindowHeight){ finalView host = mView; host.layout( 0, 0, host.getMeasuredWidth(), host.getMeasure...

weixin_34697393的博客 498

Android——View的工作流程

文章目录View的工作流程View的工作流程入口DecorView被加载到Window中MeasureSpecView的measure流程View的measure流程ViewGroup的measure流程View的layout流程View的draw流程步骤1:绘制背景步骤3:绘制View的内容步骤4:绘制子View步骤6:绘制装饰 View的工作流程 View的工作流程,指的就是measure、l...

PdKingLiu 649

《建造我的Android技能塔之沙粒三:View工作流程》

View工作流程 1.自定义View流程 开始 -> 构造函数 -> onMeasure() ->onSIzeChanged() ->onLaout() ->onDraw() -> 视图状态改变 -> 完成 构造函数:View初始化 onMeasure:测量View大小 onSizeChanged:确定View大小 onLayout:确定子View布局 onDraw:实际绘制内容 2.MeasureSpec MeasureSpec代表一个32位Int值,高2

weixin_43800587的博客 399
上一篇: Android Framework中的PolicyManager简介
下一篇: OpenGL之gluLookAt()函数
cding1818
博客等级 码龄17年 963粉丝 154原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值