热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android中activity从创建到显示的基本介绍

这篇文章主要给大家介绍了关于Android中activity从创建到显示的相关资料,文中通过示例代码介绍的非常详细,对各位Android初学者们具有一定的参考学习价值,需要的朋友们下面随着小编来一起看看吧。

前言

说道Android中的Activity,如果你做过iOS开发的话,Activity类似于iOS中的ViewController(视图控制器)。在应用中能看到的东西都是放在活动中的。活动是安卓开发比较重要的东西,是用户交互和数据的入口。本篇博客要介绍的内容是活动的创建,活动的跳转与值的透传。

iOS中的ViewController也是有自己的生命周期的,了解Activity或者ViewController的生命周期是很有必要的,本文将详细的给大家介绍关于Android中activity从创建到显示的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。

activity是我们平常开发最常用的一个组件,我们有必要了解activity的创建以及显示的过程,这些应该作为我们的储备知识。

Activity的创建

Activity的创建以及初始化的过程是在ActivityThread#performLaunchActivity方法中,在这个方法中,有以下几个关键点,

  • 创建Activity
  • Activity#attach
  • Instrumentation#callActivityOnCreate
  • Activity#performStart
  • Instrumentation#callActivityOnPostCreate

这个地方能看到Activity生命周期的一小部分。我们需要对其中一些点进行学习,在这些点里面都有一些非常重要的操作。

创建Activity的过程就不说了,直接反射。我们重点说下attach方法,

Activity#attach

attach部分代码如下

mWindow = new PhoneWindow(this, window);
mWindow.setWindowControllerCallback(this);
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);

在Activity的attach方法中,很关键的一点就是初始化Window,从这里就能看到,Window的实现类,是PhoneWindow。PhoneWindow的创建对于我们后面的操作很重要。

Activity#onCreate

public void callActivityOnCreate(Activity activity, Bundle icicle,
  PersistableBundle persistentState) {
 prePerformCreate(activity);
 activity.performCreate(icicle, persistentState);
 postPerformCreate(activity);
}

在activity.performCreate中,会调用activity的onCreate方法,这个是我们平常开发中非常熟悉的,在onCreate中,我们调用setContentView去填充布局,并进行一些初始化操作

setContentView

到了我们相当熟悉的setContentView,在setContentView中,会调用PhoneWindow的setContentView方法。我们简单看下PhoneWindow的setContentView

public void setContentView(int layoutResID) {
 // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
 // decor, when theme attributes and the like are crystalized. Do not check the feature
 // before this happens.
 if (mCOntentParent== null) {
  installDecor();
 } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
  mContentParent.removeAllViews();
 }
 if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
  final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
    getContext());
  transitionTo(newScene);
 } else {
  mLayoutInflater.inflate(layoutResID, mContentParent);
 }
 mContentParent.requestApplyInsets();
 final Callback cb = getCallback();
 if (cb != null && !isDestroyed()) {
  cb.onContentChanged();
 }
 mCOntentParentExplicitlySet= true;
}

在PhoneWindoe的setContentView方法中,会进行初始化DecorView,并将我们设置的布局加载到contentparent中。installDecor的具体逻辑我们这里就不多说了。

resume过程

在ActivityThread#handleResumeActivity方法中,有两个关键点。

  • performResumeActivity
  • Window#addView

performResumeActivity中会调用activity的performResume,performResume中会调用onResume,然后进入onresume声明周期中

我们重点说下addView以及后续的处理。

addView

wm.addView(decor, l);

这里的wm是WindowManager,是在attach法法中,通过setWindowManager来实现初始化的,对应的实例为WindowManagerImpl的一个实例。那么,我们去看下WindoeManageImpl的addView方法,在这个方法中,直接调用WindowManagerGlobal的addView方法,我们关心的中点转移了。其中最关键的diam是如下几行。

root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
root.setView(view, wparams, panelParentView);

首先创建一个ViewRootImpl,然后setView。ViewRootImpl#setView方法代码较长,我们能发现requestLayout这个方法,进去看下。

@Override
public void requestLayout() {
 if (!mHandlingLayoutInLayoutRequest) {
  checkThread();
  mLayoutRequested = true;
  scheduleTraversals();
 }
}

在这里,进行了首次线程检查。

void scheduleTraversals() {
 if (!mTraversalScheduled) {
  mTraversalScheduled = true;
  mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
  mChoreographer.postCallback(
    Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
  if (!mUnbufferedInputDispatch) {
   scheduleConsumeBatchedInput();
  }
  notifyRendererOfFramePending();
  pokeDrawLockIfNeeded();
 }
}

Choreographer,post了一个Callback,这个callback是view刷新的核心所在。我们看下TraversalRunnable的run方法,

final class TraversalRunnable implements Runnable {
 @Override
 public void run() {
  doTraversal();
 }
}
void doTraversal() {
 if (mTraversalScheduled) {
  mTraversalScheduled = false;
  mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);
  if (mProfile) {
   Debug.startMethodTracing("ViewAncestor");
  }
  performTraversals();
  if (mProfile) {
   Debug.stopMethodTracing();
   mProfile = false;
  }
 }
}

在doTraversal中,又会调用performTraversals方法,我们看下performTraversals方法是干啥的。这个方法非常非常的长,但是在这个方法中,有非常关键的performMeasure,performLayout,performDraw等方法,至此,进入的View的的三大过程,,三大过程之后,就显示在我们面前了。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。


推荐阅读
  • 本文详细介绍了PHP中的几种超全局变量,包括$GLOBAL、$_SERVER、$_POST、$_GET等,并探讨了AJAX的工作原理及其优缺点。通过具体示例,帮助读者更好地理解和应用这些技术。 ... [详细]
  • 本文概述了在GNU/Linux系统中,动态库在链接和运行阶段的搜索路径及其指定方法,包括通过编译时参数、环境变量及系统配置文件等方式来控制动态库的查找路径。 ... [详细]
  • 本文介绍如何使用 Python 计算两个时间戳之间的时间差,并将其转换为毫秒。示例代码展示了如何通过 `time` 和 `datetime` 模块实现这一功能。 ... [详细]
  • 使用 ModelAttribute 实现页面数据自动填充
    本文介绍了如何利用 Spring MVC 中的 ModelAttribute 注解,在页面跳转后自动填充表单数据。主要探讨了两种实现方法及其背后的原理。 ... [详细]
  • 使用REM和媒体查询实现响应式布局
    本文介绍如何利用REM单位和媒体查询(Media Queries)来创建适应不同屏幕尺寸的网页布局。通过具体示例,展示在不同屏幕宽度下如何调整页面元素的样式。 ... [详细]
  • 神策数据分析基础
    本文介绍了基于用户行为的数据分析方法,包括业务问题的提出与定义、具体行为的识别及统计分析流程。同时,详细阐述了如何利用事件模型(Event Model)来描述用户行为,以及在实际应用中的案例分析。 ... [详细]
  • 2023年1月28日网络安全热点
    涵盖最新的网络安全动态,包括OpenSSH和WordPress的安全更新、VirtualBox提权漏洞、以及谷歌推出的新证书验证机制等内容。 ... [详细]
  • Docker基础入门与环境配置指南
    本文介绍了Docker——一款用Go语言编写的开源应用程序容器引擎。通过Docker,用户能够将应用及其依赖打包进容器内,实现高效、轻量级的虚拟化。容器之间采用沙箱机制,确保彼此隔离且资源消耗低。 ... [详细]
  • 本文列举了构建和运行 Struts2 应用程序所需的核心 JAR 文件,包括文件上传、日志记录、模板引擎等关键组件。 ... [详细]
  • 如何高效学习鸿蒙操作系统:开发者指南
    本文探讨了开发者如何更有效地学习鸿蒙操作系统,提供了来自行业专家的建议,包括系统化学习方法、职业规划建议以及具体的开发技巧。 ... [详细]
  • egg实现登录鉴权(七):权限管理
    权限管理包含三部分:访问页面的权限,操作功能的权限和获取数据权限。页面权限:登录用户所属角色的可访问页面的权限功能权限:登录用户所属角色的可访问页面的操作权限数据权限:登录用户所属 ... [详细]
  • 本文介绍了用户界面(User Interface, UI)的基本概念,以及在iOS应用程序中UIView及其子类的重要性和使用方式。文章详细探讨了UIView如何作为用户交互的核心组件,以及它与其他UI控件和业务逻辑的关系。 ... [详细]
  • 本文详细介绍了如何使用Rufus工具制作一个兼容UEFI启动模式的Windows Server 2008 R2安装U盘,包括必要的软件和步骤。 ... [详细]
  • Windows环境下Oracle数据库迁移实践
    本文详细记录了一次在Windows操作系统下将Oracle数据库的控制文件、数据文件及在线日志文件迁移至外部存储的过程,旨在为后续的集群环境部署做好准备。 ... [详细]
  • 本文探讨了如何利用 Android 的 Movie 类来展示 GIF 动画,并详细介绍了调整 GIF 尺寸以适应不同布局的方法。同时,提供了相关的代码示例和注意事项。 ... [详细]
author-avatar
大王水灵灵_598
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有