Android四大组件之Activity

Android四大组件之Activity作者:白璐日期:2020/2/22文章目录Android四大组件之Activity概述活动程序(Activity)Activity简介Activity生命周期Intent(意图)创建一个ActivityActivity的启动模式Activity的其他属性拓展学习Activity任务与任务管理栈概述Android应用程序是由下列4个组件构成,分别...
摘要由CSDN通过智能技术生成

Android四大组件之Activity

作者:白璐
日期:2020/2/22

概述

Android应用程序是由下列4个组件构成,分别是:

  • 活动程序(Activity)
  • 服务程序(Service)
  • 广播接收器(Broadcast Receiver)
  • 内容提供器(Content Provider)

活动程序(Activity)

Activity简介

Activity是一个Android的应用组件,它提供屏幕进行交互。每个Activity都会获得一个用于绘制其用户界面的窗口,窗口可以充满哦屏幕也可以小于屏幕并浮动在其他窗口之上。
  一个应用通常是由多个彼此松散联系的Activity组成,一般会指定应用中的某个Activity为主活动,也就是说首次启动应用时给用户呈现的Activity。将Activity设为主活动的方法,如下面代码所示需要在AndroidManifest.xml文件中添加以下内容:

<application>
     ....
    <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
     </activity>
     ....
</application>     

当然Activity之间可以进行互相跳转,以便执行不同的操作。每当新Activity启动时,旧的Activity便会停止,但是系统会在堆栈也就是返回栈中保留该Activity。当新Activity启动时,系统也会将其推送到返回栈上,并取得用户的操作焦点。当用户完成当前Activity并按返回按钮是,系统就会从堆栈将其弹出销毁,然后回复前一Activity。
  当一个Activity因某个新Activity启动而停止时,系统会通过该Activity的生命周期回调方法通知其这一状态的变化。Activity因状态变化每个变化可能有若干种,每一种回调都会提供执行与该状态相应的特定操作的机会。

Activity生命周期

下图中展示了activity的重要的状态改变路径。矩形中的代表你可以在活动在两种状态间改变时你可以实现的回调方法去执行想要的操作。而带有颜色的椭圆形代表着activity的主要状态。
activity生命周期

各生命周期状态说明

方法 描述
onCreate() 当Activity第一次创建时调用。该方法(如果有)会提供给你一个包含之前活动的冻结状态信息bundle包。
onStart() 当Activity被展示在用户眼前时调用。如果活动出现在前台紧接着是onResume(),如果活动直接隐藏则紧接着是onStop()。
onRestart() 当Activity被停止后调用,在重新开始之前
onResume() 当Activity将开始与用户进行交互时调用。在这个时间点你的活动将会在活动堆栈的顶端,用户输入将会访问它。
onPause() 当系统将要恢复一个之前的活动。这是一个有代表性的常常用于提交未被存储的改动信息为持久数据,停止动画和消耗CPU的东西等。实现该方法必须要特别的迅速,因为在此方法返回之前,下一个活动将不会恢复。如果活动将返回到前台则接下来调用onResume(),如果要隐藏到用户看不见的地方时,则调用onStop();
onStop() 当另一个活动被恢复且完全覆盖该活动,而该Activity将不在展示给用户时调用。这种情况将发生在一个新的活动将被开始,一个退出的活动将被恢复,又或者该活动将要被销毁。如果该活动将恢复与用户交互则调用onRestart(),如果该活动将被销毁则调用onDestory()。
onDestory() Activity被销毁钱最后一个被调用的方法。这个方法将会发生因为活动将会结束(在活动中调用finish()方法,或者系统临时销毁该实例节约空间。你可以使用isFinishing()方法区别这两种场景)。

阶段状态
一个Activity从本质上讲拥有4种状态:
Activity4种主要状态.png

  • 运行 :如果当前的activity在前台界面上时(堆栈顶端)。
  • 暂停:如果activity被另一个非全屏活动强占焦点并覆盖时(如弹窗dialog),它将会暂停。一个暂停的活动也是完全活跃的(它的所有的状态和成员信息将会保留,但activity本身将不会再依附于WindowsManager了),在内存极度缺乏的状态会被系统杀死。
  • 停止:如果activity完全被另一个全屏活动遮挡住时,它将会停止。该活动也仍保留全部的状态和成员信息,但将会被隐藏起来不再展示给用户,并且当内存在其他地方被需要时该活动就将会被系统杀死。
  • 重启:如果activity处于暂停或者停止状态,系统将会在内存中终止该活动无论是结束活动或者杀死进程。当它再一次展示给用户时,它必须是完全重启并且恢复到之前的状态。

状态转换
Activity状态转换
  上图中我们可以看到Activity在生命周期状态进行转换的过程中,activity本身是在什么时候调用的onSaveInstanceState()方法与onRestoreInstanceState()方法来进行重要信息的存储与恢复的。因为在蜂巢版本之前onSaveInstanceState()方法只有在activity异常退出时才会调用,所以我们应该在onPause()方法中进行信息持久化存储的操作,生命周期可以调用onSaveInstanceState()方法来进行信息持久化存储的操作。

常见情况下生命周期的回调
(A与B表示不同的Activity)

情况 描述
第一次启动A onCreate() -> onStart() -> onResume()
从 A 跳转到 B A_onPause() -> B_onCreate() -> B_onStart() -> B_onResume() -> A_onStop()
从 B 再次回到 A B_onPause() -> A_onRestart() -> A_onStart() -> A_onResume() -> B_onStop()
用户按 home 键 onPause() -> onStop()
按 home 键后回到应用 onRestart() -> onStart() -> onResume()
用户按电源键屏保 onPause() -> onStop()
用户按电源键亮屏 onRestart() -> onStart() -> onResume()
用户按 back 键回退 onPause() -> onStop() -> onDestroy()

异常情况下生命周期详解
  当 Activity 在运行过程中发生一些情况时,生命周期流程也会发生变化。常见的异常情况有两种,一种是资源配置改变;另一是内存不足导致生命周期流程发生变化。

  1. 资源配置改变导致 Activity 重建
       资源配置最常见的情况就是横竖屏切换导致资源的变化,当程序启动时,会根据不同的配置加载不同的资源,例如横竖屏两个状态对应着两张不同的资源图片。如果在使用过程中屏幕突然旋转,那么 Activity 就会因为系统配置发生改变而销毁重建,加载合适的资源。
  2. 低优先级 Activity 由于内存不足被杀死
      后台可以同时运行多个任务,当设备的内存空间不足时,系统为了保证用户的体验,会按照进程优先级将一些低优先级的进程杀死以会回收内存资源,后台 Activity 就有可能会被销毁。
    系统回收进程的优先级:
    (1) 前台进程
      持有用户正在交互的 Activty,即生命周期处于 onResume 状态的活动。该进程有绑定到正在交互的 Activity 的 service 或前台 service。
    (2) 可见进程
      这种进程虽然不在前台,但是仍然可见。该进程持有的 Activity 执行了 onPause 但未执行 onStop 。例如原活动启动了一个 dialog 主题的 Activity,但此时原活动并非完全不可见。该进程有 service 绑定到可见的或前台 Activity。
    (3)服务进程
      进程中持有一个 service,同时不属于上面两种情况。
    (4)后台进程
      不属于上面三种情况,但进程持有一个不可见的 Activity,即执行了 onStop 但未执行 onDestory 的状态。
    (5)空进程
      不包含任何活跃的应用组件,作用是加快下次启动这个进程中组件所需要的时间,优先级低。

异常情况下的处理
  在发生异常情况后,用户再次回到 Activity,原 Activity 会重新建立,原已有的数据就会丢失,比如用户操作改变了一些属性值,重建之后用户就看不到之前操作的结果,在异常的情况下如何给用户带来好的体验,有两种办法。

  1. 数据保存
      第一种就是系统提供的 onSaveInstanceStateonRestoreInstanceState 方法,onSaveInstanceState 方法会在 Activity 异常销毁之前调用,用来保存需要保存的数据,onRestoreInstanceState 方法在 Activity 重建之后获取保存的数据。
      在活动异常销毁之前,系统会调用 onSaveInstanceState,可以在 Bundle 类型的参数中保存想要的信息,之后这个 Bundle 对象会作为参数传递给 onRestoreInstanceStateonCreate 方法,这样在重新创建时就可以获取数据了。
      关于 onSaveInstanceState 与 onRestoreInstanceState 方法需要注意的一些问题:
      1. onSaveInstanceState 方法的调用时机是在 onStop 之前,与 onPause 没有固定的时序关系。而 onRestoreInstanceState 方法则是在onStart 之后调用。
      2. 正常情况下的活动销毁并不会调用这两个方法,只有当活动异常销毁并且有机会重现展示的时候才会进行调用,除了资源配置的改变外,activity 因内存不足被销毁也是通过这两个方法保存数据。
      3. 在 onRestoreInstanceStateonCreate 都可以进行数据恢复工作,但是根据官方文档建议采用在 onRestoreInstanceState 中去恢复。
      4. 在 onSaveInstanceStateonRestoreInstanceState 这两个方法中,系统会默认为我们进行一定的恢复工作,具体地讲,默认实现会为布局中的每个 View 调用相应的 onSaveInstanceState() 方法,让每个视图都能提供有关自身的应保存信息。Android 框架中几乎每个小部件都会根据需要实现此方法,以便在重建 Activity 时自动保存和恢复付 UI 所做的任何可见更改。例如 EditText 中的文本信息、ListView 中的滚动位置等。也可以通过 android:saveEnabled属性设置为 “false”或通过调用 setSaveEnabled() 方法显式阻止布局内的视图保存其状态,通常不会将该属性停用,除非想要以不同方式恢复 Activity IU 的状态。
      5. onSaveInstanceState() 常见的触发场景有:横竖屏切换、按下电源键、按下菜单键、切换到别的 Activity 等;onRestoreInstanceState() 常见的触发场景有:横竖屏切换、切换语言等等。
  2. 防止重建
      在默认情况下,资源配置改变会导致活动的重新创建,但是可以通过对活动的 android:configChanges 属性的设置使活动防止重新被创建。
    android:configChanges 属性值
属性值 含义
mcc SIM 卡唯一标识IMSI(国际移动用户标识码)中的国家代码,由三位数字组成,中国为:460,这里标识 mcc 代码发生了变化
mnc SIM 卡唯一标识 IMSI(国际移动用户标识码)中的运营商代码,有两位数字组成,中国移动 TD 系统为 00 ,中国联通为 01,电信为 03,此项标识 mnc 发生了改变
locale 设备的本地位置发生了改变,一般指的是切换了系统语言
touchscreen 触摸屏发生了改变
keyboard 键盘类型发生了改变,比如用户使用了外接键盘
keyboardHidden 键盘的可访问性发生了改变,比如用户调出了键盘
navigation 系统导航方式发生了改变
screenLayout 屏幕布局发生了改变,很可能是用户激活了另外一个显示设备
fontScale 系统字体缩放比例发生了改变,比如用户选择了个新的字号
uiMode 用户界面模式发生了改变,比如开启夜间模式 -API8 新添加
orientation 屏幕方向发生改变,比如旋转了手机屏幕
screenSize 当屏幕尺寸信息发生改变(当编译选项中的 minSdkVersion 和 targeSdkVersion 均低于 13 时不会导致 Activity 重启 ) API 13 新添加
smallestScreenSize 设备的物理尺寸发生改变,这个和屏幕方向没关系,比如切换到外部显示设备 -API13 新添加
layoutDirection 当布局方向发生改变的时候,正常情况下无法修改布局的 layoutDirection 的属性 -API17 新添加

可以在属性中声明多个配置值,方法使用 “|” 字符分割这些配置值。

API 级别 13 或更高版本的应用时,若要避免由于设备方向改变(横竖屏切换)而导致运行时重启,则除了 “orientation” 值之外,还必须添加“screenSize”值。
  当其中一个配置发生变化时,Activity 不会重启。相反,Activity 会收到对 onConfigurationChanged() 的调用。向此方法传递 Configuration 对象指定新设备配置。可以通过读取 Configuration 中的字段,确定新配置,然后通过更新界面中使用的资源进行适当的更改。

关于 Activity 的不常用的回调方法

  1. onPostCreate()
      onPostCreate() 方法是指 onCreate() 方法彻底执行完毕的回调。一般我们都没有实现这个方法,它的作用是在代码开始运行之前,调用系统做最后的初始化工作。现在知道的做法是使用 ActionBarDrawerToggle 时在屏幕旋转的时候在 onPostCreate() 中同步下状态。
  2. onPostResume()
      onPostResume()onPostCreate() 方法类似,onPostResume() 方法在 onResume()方法彻底执行完毕的回调。 onCreate()方法中获取某个 View 的高度和宽度时,返回的值是 0 ,因为这个时候 View 可能还没初始化好,但是在 onPostResume()中获取就不会有问题,因为 onPostResume() 是在 onResume()彻底执行完毕的回调。
  3. onContentChanged()
      当 Activity 的布局改动时,即 setContentView() 或者 addContentView()方法执行完毕时就会调用该方法。所以,Activity 中 View 的 findViewById() 方法都可以放到该方法中。
  4. onUserInteraction()
      Activity 无论分发按键事件、触摸事件或者轨迹球事件都会调用 Activity#onUserInteraction()。如果想知道用户用某种方式和你正在运行的 activity 交互,可以重写 Activity#onUserInteraction()。所有调用 Activity#onUserLeaveHint() 的回调都会首先回调 Activity#onUserInteraction()
      Activity 在分发各种事件的时候会调用该方法,注意:启动另一个 activity ,Activity#onUserInteraction()会被调用两次,一次是 activity 捕获到事件,另一次是调用Activity#onUserLeaveHint() 之前会调用 Activity#onUserInteraction()
      可以用这个方法来监控用户有没有与当前的 Activity 进行交互。
  5. onUserLeaveHint()
      当用户的操作使一个 activity 准备进入后台时,此方法会像 activity 的生命周期的一部分被调用。例如,当用户按下 Home 键,Activity#onUserLeaveHint()将会被调用。但是当来电导致 activity 自动占据前台(系统自动切换),Activity#onUserLea
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值