Activity 总结

Activity 是 Android 四大组件之一,每一个 Activity 都会得到一个用于绘制其用户界面的窗口,用户可与其进行交互。如下来总结 Activity 的重点知识。android

生命周期

正常的生命周期分析

Activity生命周期的回调主要有 onCreate()onRestart()onStart()onResume()onPause()onStop()onDestory() 几种方法,在生命周期里有三个嵌套循环git

  • Activity 的整个生命周期发生在 onCreate()onDestroy() 之间,在 onCreate() 中执行“全局”状态设置(例如状态布局),并在 onDestroy() 中释放资源。
  • Activity 的可见生命周期发生在 onStart()onStop() 之间,在这段时间内Activity对用户可见。能够在这俩个方法之间保留向用户显示 Activity 所需的资源。在整个生命周期中,当 Activity 在对用户可见和隐藏俩种状态中交替变化时,系统会屡次调用 onStart()onStop()
  • Activity 的前台生命周期发生在 onResume()onPause() 之间,Activity位于其余 Activity 以前,可与用户交互并具备输入焦点。但状态改变频繁,建议作些轻量级操做。

生命周期

  • onCreate()首次建立 Activity 时调用。在这个方法里执行全部正常的静态设置-建立视图、将数据绑定到列表等等。
  • onRestart()已中止并即将再次启动前调用。
  • onStart()在 Activity 即将对用户可见以前调用。若是 Activity 转入前台,则后接 onResume() ,若是 Activity 转入隐藏状态,则后接 onStop()
  • onResume()在 Activity 即将开始与用户进行交互以前调用。此时,Activity 处于任务栈的顶层,并具备用户输入焦点。
  • onPause()当系统即将开始继续另外一个 Activity 时调用。此方法一般用于确认对持久性数据的未保存更改,中止动画以及其余可能消耗CPU的内容。它应该迅速地执行所需操做,由于它返回后,下一个 Activity 才能继续执行。若是 Activity 返回前台,则后接 onResume() ,若是 Activity 转入对用户不可见状态,则后接 onStop()
  • onStop()在 Activity 对用户再也不可见时调用。若是 Activity 恢复与用户的交互,则后接 onRestart() ,若是 Activity 被销毁,则后接 onDestroy()
  • onDestroy()在 Activity 被销毁前调用。当 Activity 由于被调用 finish() 或系统为节省空间而暂时销毁该 Activity 实例时,可能会调用它,能够经过 isFinishing() 方法来区分。

图中周期说明

  • 正常启动一个 Activity ,回调以下:onCreate()->onStart()->onResume()
  • 当用户打开新的 Activity 或切换到桌面时,回调以下:onPause()->onStop(),有一种特殊状况:若是新的 Activity 采用了透明主题,那么当前 Activity 不会回调 onStop()
  • 当用户再次回到原 Activity 时,回调以下:onRestart()->onStart()->onResume()
  • 当用户按back键回退时,回调以下:onPause()->onStop()->onDestroy()
  • 从整个生命周期来看,onCreate()onDestroy() 配对,只会调用一次。从 Activity 的可见状态来讲,onStart()onStop() 配对,会调用屡次。从 Activity 是否在前台可交互来讲, onResume()onPause() 配对,可调用屡次。

周期相关问题

onStart()onResume()onPause()onStop() 的区别?
  • onStart()onStop() 是从 Activity 是否可见来回调的,onResume()onPause() 是从 Activity 是否位于前台来回调的。
俩个 Activity A 和 B,那么 A 启动 B 的过程当中,A 的 onPause() 与 B 的 onResume() 哪一个先执行?
  • 新 Activity 启动以前,栈顶的 Activity 须要先 onPause() 后,新的 Activity 才能启动的。

异常的生命周期分析

当 Activity 暂停或中止时,Activity 对象仍保留在内存中-有关其成员和当前状态仍处于活动状态。所以,用户在 Activity 内所作的任何更改都会获得保留,这样一来,当 Activity 返回前台时,这些更改仍然存在。
可是当资源相关的系统配置发生改变或系统内存不足时,Activity 对象可能会被销毁,这时继续 Activity 时根本没法让其状态保持无缺,而是必须在用户返回 Activity 时建立 Activity 对象,这些状态信息会由 onSaveInstanceState() 来保存。github

数据恢复

  • 当 Activity 被异常终止后,系统会调用 onSaveInstanceState() 来保存当 Activity 的状态。这个方法的调用时机是在 onStop() 以前,和 onPause() 没有既定的时序关系。当 Activity 被从新建立后,系统会调用 onRestoreInstanceState() ,而且把 Activity 销毁时经过 onSaveInstanceState() 保存的 Bundle 对象同时传递给 onRestoreInstanceState()onCreate() ,从时序上来讲, onRestoreInstanceState()onStart() 以后。
  • 没法保证系统会在销毁 Activity 前调用 onSaveInstanceState() ,由于当正常离开当前页面,显示关闭 Activity 时,不须要保存状态。并且在异常状态下没法肯定调用 onSaveInstanceState() 的时机,因此只用它来保存 Activity 的瞬间状态,不要来保存持久性数据。
  • Activity 类的 onSaveInstanceState() 默认实现会恢复部分 Activity 状态,具体地来讲,默认实现会为布局中的每一个 View 调用相应的 onSaveInstanceState() 方法,让每一个视图都能提供有关自身的应保存信息。 Android 框架中几乎每一个小部件都会根据须要实现此方法,以便在重建 Activity 时自动保存和恢复对UI所作的任何可见更改。咱们只须要为保存其状态的每一个小部件提供一个惟一的ID,若是小部件没有ID,则系统没法保存其状态。
  • 系统配置发生改变后,Activity 会被从新建立,但咱们能够指定 configChanges 属性,不从新建立。好比不想让屏幕旋转时从新建立,给 configChanges 属性添加 orientation 值,以下,android:configChanges="orientation"

任务和返回栈

  • 任务:在执行特定做业时与用户交互的一系列 Activity。
  • 返回栈:这些 Activity 按照各自的打开顺序排列在堆栈中。

当前 Activity 启动另外一个 Activity 时,该新的 Activity 会被推送到堆栈顶部,成为焦点所在。前一个 Activity 仍保留在堆栈中,可是处于中止状态。当用户按“返回”键时,当前 Activity 会从堆栈顶部弹出(被销毁),而前一个 Activity 恢复执行。堆栈中的 Activity 永远不会从新排列,仅推入和弹出堆栈,并按照“后进先出”对象结构运行。框架

启动模式

定义 Activity 的新实例如何与当前任务关联,来改变系统的默认行为。ide

standard

默认模式。系统在每次启动 一个Activity 都会从新建立一个新实例,无论这个实例是否已经存在。非 Activity 类型的 Context 没有任务栈,用 getApplicationContext 直接启动 Activity 会报错,能够加一个标志位 FLAG_ACTIVITY_NEW_TASK ,实际以 singleTask 模式启动的一个新的任务栈。布局

singleTop

栈顶复用模式。若是新的 Activity 已经位于任务栈的栈顶,那么此 Activity 不会被从新建立,同时经过 onNewIntent() 方法传递 Intent。若是新 Activity 的实例已经存在但不位于栈顶,那么新的 Activity 仍然会被从新建立。动画

singleTask

栈内复用模式。是一种单实例模式,在这种模式下,若是该 Activity 的一个实例已经存在于一个单独的任务中,系统会经过调用现有实例的 onNewIntent() 方法向其传送 Intent,而不是建立新实例。若是启动的 Activity 位于当前任务栈中,启动该 Activity 时,会把该 Activity 切换到栈顶后,还将致使它上边的 Activity 所有出栈。若是启动的 Activity 位于后台任务栈中,则整个后台任务栈会被切换到前台。spa

singleInstance

单实例模式。是一种增强的 singleTask 模式。和 singleTask 相同,只是具备此种模式的 Activity 只能单独位于一个任务栈中。code

使用

清单文件

在清单文件中声明 Activity 时,使用 <activity> 元素的 lauchMode 属性指定 Activity 应该如何与任务关联。对象

Intent 标志

启动 Activity 时,经过 startActivity() 的 Intent 中加入相应的标志,修改 Activity 与其任务的默认关联方式。

  • FLAG_ACTIVITY_NEW_TASK:产生与 “singleTask” 模式相同的行为。
  • FLAG_ACTIVITY_SINGLE_TOP:产生 “singleTop” 模式相同的行为。
  • FLAG_ACTIVITY_CLEAR_TOP:若是正在启动的 Activity 已在当前任务中运行,则会销毁倩倩任务顶部的全部 Activity ,并经过 onNewIntent() 将此 Intent 传递给 Activity 已恢复的实例(如今位于顶部),而不是启动该 Activity 的新实例。一般与 FLAG_ACTIVITY_NEW_TASK 结合使用,就会等同于“singleTask” 模式。
  • FLAG_ACTIVITY_EXCLUDE_RECENTS:具备这个标记的 Activity 不会出如今任务栈中,可用于不会经过历史列表回到这个页面的状况,效果等同于 android:exludeFromRecents="true"

Intent 匹配规则

Intent 是一个消息传递对象,能够向其余应用组件发送请求操做。

Intent 类型

  • 显示 Intent:按名称(彻底限定类名)指定要启动的组件。须要明确知道启动对象的组件信息,包括包名和类名。
  • 隐式 Intent:不会指定特定的组件,而是声明要执行的常规操做,从而容许其余应用中的组件来处理它。建立隐式 Intent 时,Android 系统经过将 Intent 的内容与设备上其余应用的清单文件中声明的 intent-filter 进行比较,若 Intent 与 intent-filter 匹配,则系统内启动该组件,如有多个匹配,则经过显示的对话框来支持用户选择要使用的应用。

当一个 Intent 同时匹配 activity 声明的任何一组 action,category 和 data 时,就可成功启动对应的应用。

action

指定要执行的通用操做的字符串。Intent 中必须有一个 action ,且必须可以和过滤规则中的某个 action 相同便可匹配成功。

category

处理 Intent 组件类型的附加信息的字符串。若是 Intent 中含有 category,那么全部的 category 都必须和过滤规则中的其中一个 category 相同。换句话说,Intent 里的category 都必须是过滤规则中的 category。Intent 能够没有 category,由于系统会默认加上 android.intent.category.DEFAULT,这时对于接收的 activity ,就必须在 intent-filter 里加上这个默认的类别了。

data

引用待操做数据和/或该数据 MIME 类型的 URI ( Uri 对象)。data 由俩部分组成, mimeType 和 URI 。

  • mimeType:指媒体类型,好比 image/jpg、audio/mpeg4-generic 和 video/* 等。
  • URI :包含的数据比较多,具体结构: <scheme>://<host>:<port>[<path>|<pathPrefix>|<pathPattern>] ,Scheme 表示 URI 的模式,如 http,file,content 等。

能够用 setData() 设置 URI,setType() 设置 MIME 类型,但同时使用时,请使用 setDataAndType() ,由于 调用 setData()setType() 会互相抵消彼此的值。匹配规则和 action 相似,它要求 Intent 中必须含有 data 数据,且 data 数据可以彻底匹配过滤规则中的某个 data 。

Extra

携带完成请求操做所需的附加信息的键值对。

Flag

Intent 的标志,来指示 Android 系统如何启动 Activity 以及启动以后如何处理。

本文发表于我的博客:http://lavnfan.github.io/,欢迎指教。

相关文章
相关标签/搜索