【Android】setContentView的学习笔记

这篇具有很好参考价值的文章主要介绍了【Android】setContentView的学习笔记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

启动一个Activity

performLaunchActivity()

ActivityThread.performLaunchActivity() 方法是 Android 系统中负责启动一个 Activity 的关键方法。

当调用startActivity()方法启动一个 Activity 时,ActivityThread 对象会接收到该请求,并调用 performLaunchActivity() 方法。

在 performLaunchActivity() 方法内部,首先会创建一个新的 ActivityRecord 对象,用于表示将要启动的 Activity。

接下来,会调用 activity.attach() 方法,该方法用于将 Activity 对象与 ActivityRecord 关联起来,并初始化相应的属性。

在 activity.attach() 方法中,首先会创建一个PhoneWindow对象。PhoneWindow 是与 Activity 关联的窗口,提供了窗口管理的功能。

然后,会调用mInstrumentation.callActivityOnCreate()方法来触发 Activity 的生命周期回调方法 onCreate()

mInstrumentation 是用于进行 Activity 生命周期调度和事件派发的工具类。它可以调用各种生命周期回调方法,如 onCreate()、onStart()、onResume() 等。

callActivityOnCreate() 方法会在主线程中调用 Activity 的 onCreate() 方法,以便执行一些初始化操作。

onCreate() 是一个重要的生命周期方法,用于在 Activity 创建时进行必要的初始化,如设置布局、获取传递的数据等。

PhoneWindow

PhoneWindow 类在 Android 中主要负责显示界面的窗口管理,它会创建以下几种类型的窗口

Activity:
当你启动一个 Activity 时,系统会为该 Activity 创建一个关联的 PhoneWindow 对象。这个 PhoneWindow 对象负责承载 Activity 的布局和界面显示。

Dialog(对话框):
Dialog 类是以对话框形式展示的窗口,它也依赖于 PhoneWindow。当你创建一个对话框时,系统会为其创建一个独立的 PhoneWindow 对象,用于承载对话框的布局和内容。

PopupWindow(弹出窗口):
PopupWindow 是一种浮动在其他视图之上的窗口,也需要 PhoneWindow 进行创建和管理。当你创建一个 PopupWindow 实例时,系统会为其自动创建一个 PhoneWindow 对象。

Toast(消息提示):
Toast 的创建不直接依赖于 PhoneWindow,但在显示 Toast 消息时,会通过 PhoneWindow 创建一个临时的窗口用于显示内容。

当创建的Activity继承Activity时,调用setContentView

PhoneWindow.setContentView():
当在 Activity 中调用 setContentView(layoutResID) 方法时,会触发 PhoneWindow 的 setContentView() 方法。其主要目的是创建一个 DecorView 并获取到内容视图。

installDecor():
installDecor() 方法是 PhoneWindow 中的一个私有方法,它负责创建 DecorView 并获取到 mContentParent(内容视图的父容器)

generateDecor(-1):
在 installDecor() 方法中,会调用 generateDecor() 方法来生成一个 DecorView 对象,并将其存储在 mDecor 成员变量中。这个 DecorView 是 PhoneWindow 中承载界面内容的根视图。

generateLayout(mDecor):
generateLayout() 方法是用于生成布局的辅助方法,通过传入的 DecorView 返回一个 ViewGroup 对象作为内容视图的父容器,并将其存储在mContentParent成员变量中。

mDecor.onResourcesLoaded(mLayoutInflater, layoutResource):
在 generateLayout() 方法中,会调用 mDecor 的 onResourcesLoaded() 方法,该方法用于处理资源加载完成后的相关操作。

mLayoutInflater.inflate(layoutResID, mContentParent):
最后,在 PhoneWindow 中调用 mLayoutInflater.inflate(layoutResID, mContentParent) 方法,将指定的布局资源(例如 R.layout.activity_main)填充到 mContentParent 中,从而将布局渲染到界面上。

【Android】setContentView的学习笔记,Android学习笔记,android,学习,笔记

当创建的Activity继承AppCompatActivity时,调用setContentView

继承 AppCompatActivity 的流程相比于继承 Activity 会多出一些处理与兼容性相关的步骤。

AppCompatDelegate.setContentView():
当你在 AppCompatActivity 中调用 setContentView(layoutResID) 方法时,会触发 AppCompatDelegate setContentView() 方法。它负责确保正确的子布局(subDecor)被创建并设置为内容视图

ensureSubDecor():
ensureSubDecor() 方法被调用用来确保子布局 subDecor 被正确创建。它会调用 createSubDecor() 方法来生成 subDecor 对象。

createSubDecor():
createSubDecor() 方法主要负责创建 subDecor 对象,即承载界面内容的根视图。在这个方法中,会调用 ensureWindow() 来确保关联的PhoneWindow被正确创建,然后通过 mWindow.getDecorView() 获取到 PhoneWindow 的根视图。

复制内容视图:
createSubDecor()方法中,会将原始的内容视图(android.R.id.content)的子视图复制到一个新的容器视图(R.id.action_bar_activity_content)中,并将原始的内容视图的 id 设置为 NO_ID,将新容器视图的 id 设置为 android.R.id.content

设置 subDecor:
最后,通过mWindow.setContentView(subDecor)方法将 subDecor 设置为 PhoneWindow 的内容视图

布局创建与解析:
在创建布局的过程中,会使用LayoutInflater解析指定的布局资源,并通过反射创建相应的 View 对象。如果布局标签名包含了包名,则直接通过反射创建对应的 View 对象;否则,会通过 onCreateView() 方法来创建 View 对象。在创建完毕后,将会进行子视图的创建解析,最终得到整个布局的视图结构。

【Android】setContentView的学习笔记,Android学习笔记,android,学习,笔记

LayoutInflate参数的作用

LayoutInflater 是 Android 中的一个类,用于将布局资源文件转换为对应的视图对象。它的主要作用是根据指定的布局资源文件(XML 文件)创建对应的视图层次结构,并将其实例化为 View 对象。

通过 LayoutInflater,可以在代码中动态地加载和创建布局,而不需要使用静态的 XML 布局文件。这样可以在运行时根据需要动态地创建不同的视图,并将其添加到相应的父容器中。

LayoutInflater 的几个参数的作用如下:

layoutResID:
这是需要加载的布局资源文件的 ID。通过指定资源文件的 ID,LayoutInflater 可以根据该 ID 加载对应的布局文件。

root:
这是加载布局时所需的父容器(parent)。在加载布局时,如果需要将布局添加到一个父容器中,可以将其指定为 root。如果不需要将布局添加到父容器中,可以将 root 设置为 null。

attachToRoot:
这是一个标志位,用于指示是否将加载后的布局视图添加到 root 父容器中。如果设置为 true,则会将加载后的布局视图直接附加到 root 父容器中;如果设置为 false,则只会返回加载后的布局视图,而不会将其添加到 root 父容器中。

举例
// 方式一:将布局添加成功
View view = inflater.inflate(R.layout.inflate_layout, ll, true);
// 方式二:报错,一个View只能有一个父亲(The specified child already has a parent.)
View view = inflater.inflate(R.layout.inflate_layout, ll, true); // 已经addView
ll.addView(view);
// 方式三:布局成功,第三个参数为false
// 目的:想要 inflate_layout 的根节点的属性(宽高)有效,又不想让其处于某一个容器中
View view = inflater.inflate(R.layout.inflate_layout, ll, false);
ll.addView(view);
// 方式四:root = null,这个时候不管第三个参数是什么,显示效果一样
// inflate_layout 的根节点的属性(宽高)设置无效,只是包裹子View,
// 但是子View(Button)有效,因为Button是出于容器下的
View view = inflater.inflate(R.layout.inflate_layout, null, false);
ll.addView(view);
备注:View 没有父容器 =>>> 尺寸大小 参数的设置无效

为什么requestWindowFeature()要在setContentView()之前调用

requestWindowFeature() 方法实际上是调用了 PhoneWindow.requestFeature() 方法。这个方法会检查一个名为 mContentParentExplicitlySet 的变量是否为 true,如果是则会报错。

在 PhoneWindow.setContentView() 方法调用之前调用 requestWindowFeature() 的目的是确保在设置布局内容之前先请求窗口功能。如果先调用 setContentView(),那么 mContentParentExplicitlySet 变量会在 setContentView() 方法内部被设置为 true,这样再调用 requestWindowFeature() 就会引发错误。

因此,正确的顺序是先调用 requestWindowFeature() 请求窗口功能,然后再调用 setContentView() 设置布局内容。这样可以避免错误发生,并正确启用所需的窗口功能。

为什么这么设计呢?

Android 中的窗口布局是通过 DecorView 来实现的。DecorView 是一个表示活动窗口所有内容的根视图,包括标题栏、内容区域和其他装饰元素。

requestWindowFeature() 方法的设计是为了在创建 DecorView 之前设置窗口的特征。这样可以确保在创建活动窗口时,根据特征的设置来决定如何绘制窗口的外观和行为。

当调用 setContentView() 方法时,将会创建 DecorView 和添加内容区域。在这之前,系统需要知道要使用哪些窗口特征来决定如何绘制 DecorView。这就是为什么应该在调用 setContentView() 之前先调用 requestWindowFeature() 的原因。

通过在 requestWindowFeature() 中设置特征,我们可以控制窗口的外观和功能,例如是否显示标题栏、进度条等。这种设计方式使得我们能够在活动加载布局之前对窗口进行必要的配置

为什么 requestWindowFeature(Window.FEATURE_NO_TITLE);设置无效?

requestWindowFeature(Window.FEATURE_NO_TITLE) 设置无效的原因是因为你的活动继承自 AppCompatActivity,而不是直接继承自 Activity。在 AppCompatActivity 中,标题栏的处理方式不同于传统的 Activity。

在 AppCompatActivity 中,应该使用 supportRequestWindowFeature(Window.FEATURE_NO_TITLE) 方法来请求隐藏标题栏。这是因为 AppCompatActivity 提供了对兼容性特性的支持,可以确保在不同版本的 Android 上一致地隐藏标题栏。

supportRequestWindowFeature() 方法是 AppCompatActivity 的一个方法,用于设置窗口特征。通过调用 supportRequestWindowFeature(Window.FEATURE_NO_TITLE),可以请求在活动中隐藏标题栏。

所以,如果活动继承自 AppCompatActivity,并且想要隐藏标题栏,应该使用 supportRequestWindowFeature(Window.FEATURE_NO_TITLE) 方法,而不是 requestWindowFeature(Window.FEATURE_NO_TITLE)。前者会确保正确处理标题栏的隐藏。文章来源地址https://www.toymoban.com/news/detail-610504.html

到了这里,关于【Android】setContentView的学习笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Android】学习笔记

    目录 准备 界面:view控件 LayoutCreator 事件监听OnClickListener 转跳页面Intent Intent传递数据 Toast和AlertDialog Gson使用 OKhttp3的基本使用 post方法 get方法 轻量级存储SharedPreference ListView基本使用 1、SimpleAdapter 2、较复杂的数据绑定 3、ListView的事件监听 开发软件配置:Android Studio, API34 打

    2024年02月05日
    浏览(32)
  • 《Android学习笔记》Android12蓝牙扫描不到设备的权限问题

    Android12 关于蓝牙这部分新增了 BLUETOOTH_SCAN 、 BLUETOOTH_ADVERTISE 和 BLUETOOTH_CONNECT 权限,这些权限都属于敏感权限,都需要在代码中动态申请。移除了Android11 及以下版本中必须申请的位置权限[ FINE_LOCATION ] 和 [ COARES_LOCATION ]。 1、在Manifest.xml清单文件中添加对应的权限。 其中 An

    2024年02月15日
    浏览(35)
  • Android学习笔记 - Camera(1)

    在APP开发中会有很多业务使用到Camera,对于一些基础的功能,调用系统的拍摄功能就可以满足要求。但是需要自定义UI界面时,例如将摄像头捕获的视图展示在页面上的时候就需要使用到Camera这个类了。 本篇会介绍哪些知识点: 什么是SurfaceView?有什么作用?何为双缓冲机制

    2024年02月03日
    浏览(29)
  • Android学习笔记 - 常用的布局

    Android中有六种的布局方式,分别是:LinearLayout(线性布局)、RelativeLayout(相对布局)、TableLayout(表格布局)、FrameLayout(帧布局)、AbsoluteLayout(绝对布局)、GridLayout(网格布局)。在开发中,我们用的最多的就是线性布局和相对布局。 线性布局是我们在开发中用的最多的一种布局方式。

    2024年02月04日
    浏览(31)
  • 【Android学习笔记】事件监听机制详解

    两种事件处理机制 基于监听的事件处理 基于回调的事件处理 涉及到的三类对象 Event Source事件源,指各个组件。 Event 界面组件上发生的特定的事情,。 Event Listener监听事件源发生的事情。并对各种事情作出相应的响应。 Event Handler事件处理器,当事件监听器捕获事件后,由响

    2024年02月11日
    浏览(49)
  • 【Android】APP启动优化学习笔记

    用户体验: 应用的启动速度直接影响用户体验。用户希望应用能够快速启动并迅速响应他们的操作。如果应用启动较慢,用户可能会感到不满,并且有可能选择卸载或切换到竞争对手的应用。通过启动优化,可以提高应用的启动速度,让用户获得更好的使用体验。 竞争优势

    2024年02月14日
    浏览(28)
  • 【Android】底层逻辑深入了解(学习笔记)(未完)

    step by step. 目录 init启动 Zygote进程:  SystemServer处理过程 Binder: Launcher启动过程 Android系统启动流程 四大组件 Activity Service  BroadcastReceiver广播 ContentProvider内容提供者(进程内和进程间的数据共享)  Context上下文  AMS(ActivityManagerService) (在图书馆看了《Android进阶解密》,

    2024年02月15日
    浏览(28)
  • Android ContentProvider基础知识学习笔记

    1、动态申请权限 2、读取手机联系人 3、创建自己的ContentProvider (1) onCreate()。初始化ContentProvider的时候调用。通常会在这里完成对数据库的创建和升级等操作,返回true表示ContentProvider初始化成功,返回false则表示失败。 (2) query()。从ContentProvider中查询数据。uri参数用于确定查

    2024年04月10日
    浏览(35)
  • Android学习笔记 - 广播的注册与接收

    目录 一、简介 二、广播接收器的注册 广播是Android四大组件之一,是以intent为媒介在组件间进行传播数据的一种机制。 从整体来看,广播主要有三个动作和三个角色。三个动作包含“注册广播接收器”、“发送广播”和“接收广播”;三个动作包含发送方、接收方和中间人

    2023年04月23日
    浏览(78)
  • 《Android 移动应用基础教程(Android Studio)(第2版)》【学习笔记】【2023春】【附源码】

    《Android 移动应用基础教程(Android Studio)(第2版)》黑马程序员 源代码 Android——六大基本布局总结/CSDN@小马 同学 【Android】线性布局(LinearLayout)最全解析/CSDN@Teacher.Hu 一个不错的计算器界面👇 Android Studio App LinearLayout多层布局嵌套/CSDN@pythontojava 一个简单的布局👇 Andro

    2024年02月01日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包