该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列。该系列引用了《Android开发艺术探索》以及《深入理解Android 卷Ⅰ,Ⅱ,Ⅲ》中的相关知识,另外也借鉴了其他的优质博客,在此向各位大神表示感谢,膜拜!!!另外,本系列文章知识可能需要有一定Android开发基础和项目经验的同学才能更好理解,也就是说该系列文章面向的是Android中高级开发工程师。*


第三篇了,,接着上一篇说 (怎么感觉没人评论呢)

上一篇我们只上图了没有具体分析,,下面干货来了


先分析setContentView(虽然这个网上一搜到处都是,不过我的不一样哦)

还是先上代码

activity_main.xml(没变哦)

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.helloword.MainActivity"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" /> </android.support.constraint.ConstraintLayout>

MainActivity.java(变了哦)

package com.helloword;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//注意我们先注释掉该句
//setContentView(R.layout.activity_main);
}
}

不是要分析setContentView(R.layout.activity_main)为什么注释掉呢,,先别急,我们先运行一下,居然没有崩溃,只是得到一个空白内容页面(这个显示跟Activity Theme主题设置相关,我的是默认Theme)如下

我们来看一下View层级图

需要注意的地方我用红色框框圈住了,可以看到我们在没有写setContentView(R.layout.activity_main)的时候,程序依然可以正常运行,并显示出Title。而且结合上一篇中

这个图的话,我们发现除了红色区域没有,其他区域的都有。那么该Activity的显示的基础——PhoneWindow和顶级View——DecorView是什么时候创建的呢?

其实该系列的第一篇就提到了一些,在第一篇Android开发之漫漫长途 Ⅰ——Android系统的创世之初以及Activity的生命周期 的最后我们就提到了Activity的创建工作是在android.app.ActivityThread的main函数中完成的。那么我们来分析一下该函数(我们不具体分析源码,太多了),不过我会上图

好了,接着把//setContentView(R.layout.activity_main);//去掉。又得到我们熟悉的HelloWorld界面,这个界面的层级图上一篇文章Android开发之漫漫长途 Ⅱ——Activity的显示之Window和View(1)已经上过了这里我们重新上传一下更详细的。这次我们再来看一下这个层级图是不是理解的更清晰了呢。我们的setContentView(R.layout.activity_main);内部把activity_main.xml文件解析成View,并把该View添加到contentView

注:调用setContentView(R.layout.activity_main)和不调用生成DecorView的逻辑是不一样的,如果调用了该函数会在该函数内部判断生成DecorView,如果不调用的话会在handleResumeActivity的时候判断生成这就是我们不写setContentView(R.layout.activity_main),也会生成DecorView的原因


再分析上一篇中的我们Acitivty代码

package com.helloword;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); /**
* 可以看到我们熟悉的setContentView(R.layout.activity_main)调用没有了,
*而是采用了下面的代码,运行然后居然得到了和setContentView(R.layout.activity_main)
*的一样的显示结果,难道说setContentView(R.layout.activity_main)
* 逻辑这么简单吗?我的回答是否定的,setContentView(R.layout.activity_main)
*逻辑并没有那么简单,不信的话你点击返回按钮试试看。(无法操作了哦,不是你们的手机是不是这样,反正我的手机点击返回没有作用,重写onBackPressed方法也没有调用)
*
* (注:我以下面这种方式得到了和setContentView(R.layout.activity_main)一样的显示效果
*,可这只是为了分析方便,不要模仿哦 )
*/ //① 解析.activity_main.xml文件并创建View并且指定其父View为null(即没有父View)
View view = getLayoutInflater().inflate(R.layout.activity_main,null);
//② 设置显示参数
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
1,
0,
PixelFormat.TRANSPARENT);
//③ 添加View
getWindowManager().addView(view,params);
}
}

在分析之前呢,我们已经把Android Studio 3.0自动生成的MainActivity代码差不多分析完了,相信各位读者读到这里也对Activiy的启动有了大致的了解。那为什么我们还要分析我们自己的代码呢,因为这对理解ActivityThread.main流程图的最后一步通过WindowManager添加View有巨大帮助。在我们的代码中我直接通过getLayoutInflater().inflate(R.layout.activity_main,null);把xml布局文件解析成了View,让后通过 getWindowManager().addView(view,params);添加了View。这不是跟ActivityThread.main流程图的最后一步通过WindowManager添加View不谋而合了吗。但是可以根据我们代码得到的层级图

可以看到我们View的层级图并没有我们熟悉的PhoneWindow以及DecorView。因为我们直接使用了WindowManager添加View,addView会新创建一个窗口,就像一个Dialog一样,并把View加入,除此之外棕色框框圈住的使我们熟悉的PhoneWindow以及DecorView。因此我十分反对上面的MainActivity写法哦。Android系统控件本身帮助我们做了很多事情,我们使用setContentView(R.layout.activity_main)之前便得到了一个PhoneWindow以及DecorView,并通过该函数把我们自己的布局View放到了DecorView下。所以理解这一点对后面的文章阅读至关重要。


此致,敬礼

Android开发之漫漫长途 Ⅲ——Activity的显示之Window和View(2)的更多相关文章

  1. Android开发之漫漫长途 Ⅱ——Activity的显示之Window和View(2)

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...

  2. Android开发之漫漫长途 Ⅱ——Activity的显示之Window和View(1)

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...

  3. Android开发之漫漫长途 Ⅳ——Activity的显示之ViewRootImpl初探

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...

  4. Android开发之漫漫长途 Ⅴ——Activity的显示之ViewRootImpl的PreMeasure、WindowLayout、EndMeasure、Layout、Draw

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...

  5. Android开发之漫漫长途 XI——从I到X的小结

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...

  6. Android开发之漫漫长途 Ⅵ——图解Android事件分发机制(深入底层源码)

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...

  7. Android开发之漫漫长途 番外篇——自定义View的各种姿势2

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...

  8. Android开发之漫漫长途 XIV——ListView

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...

  9. Android开发之漫漫长途 Ⅰ——Android系统的创世之初以及Activity的生命周期

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>中的相关知识,再次表示该书 ...

随机推荐

  1. NSString NSMutableString

    // NSString         //代开API文档         //Xcode -> help - Documentation and API Reference           ...

  2. (线段树)Mayor's posters --poj -- 2528

    链接: http://poj.org/problem?id=2528 覆盖问题, 要从后往前找, 如果已经被覆盖就不能再覆盖了,否则就可以覆盖 递归呀递归什么时候我才能吃透你 代码: #include ...

  3. 如何使用C++11实现C#属性概念设计

    目录(原创博客,版权所有,转载请注明出处 http://www.cnblogs.com/feng-sc) 1.概述 2.C#属性的概念  2.1.简单示例代码介绍C#中的属性  2.2.C++实现效果 ...

  4. Android热补丁技术—dexposed原理简析(阿里Hao)

    本文由嵌入式企鹅圈原创团队成员.阿里资深工程师Hao分享. 上篇文章<Android无线开发的几种常用技术>我们介绍了几种android移动应用开发中的常用技术,其中的热补丁正在被越来越多 ...

  5. 如何关闭D10 启动后自动打开的 WelCome页

    在快捷方式上 修改为 "C:\Program Files (x86)\Embarcadero\Studio\19.0\bin\bds.exe" -pDelphi -np 最后增加 ...

  6. const 用法全面总结

    C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方面查到的资料进行总结如下,期望对朋友们有所帮助. Const 是C++中常用的类型修饰符,常类型是指使用类 ...

  7. c# AOP编程:Context与方法拦截

    之前做AgentBooking时候,遇到两个问题比较棘手,一个是异常的传递与捕获:如何可以合理地在层层代码调用中统一传递并统一捕获异常.因为如果有一个做法,可以地方统一处理异常,可以使代码减少很多tr ...

  8. 挂载Linux云主机硬盘到本地计算机

      现在移动硬盘已经是每个人的生活必需品了,当然网络也是我们生活的必需品,我们现在就是要用网络存储代替硬盘存储,当然再实际使用过程中需要考虑到以下两个问题: 网络延迟 云主机磁盘IO   以上两个关键 ...

  9. 落地存储pika

    官方文档这样介绍pika pika是什么   pika 是DBA和基础架构组联合开发的类Redis 存储系统,所以完全支持Redis协议,用户不需要修改任何代码,就可以将服务迁移至pika.Pika是 ...

  10. 新建linux服务器初始化操作

    1.关闭不需要的服务 首先确定服务器有没有ntsysv命令,如果没有的话,直接使用yum安装即可. 使用ntsysv关闭不需要的服务以节省服务器资源 需要打开的服务如下: crond:周期性计划任务 ...