上回说到应用初始化加载及其生命周期,在Android系统调用Applicaiton.onCreate()
以后,继续建立并加载清单文件中注册的首个界面即主Activity
,也可称之为入口界面。主Activity
的肯定规则在Android系统编程入门系列之清单文件有介绍,本文主要介绍Android系统建立Activity
以后的生命周期流程。
在清单文件中所注册的界面均为自定义Activity
,其父类往上追溯,必须继承自android.content.Activity。html
Activity
做为四大组件之首,主要负责与系统使用者的可视化交互响应。只有深入掌握Activity
的生命周期及相关概念,才能在开发设计时游刃有余。注意,这里的生命周期介绍,与官方生命周期定义有所区别,本文中的范围更加宽泛。android
Android组件的生命周期,均是由Android系统主线程调用,若是在调用的生命周期方法内出现耗时操做,将会致使后续的生命周期方法没法被及时调用,反应到交互界面上就是应用程序卡顿甚至操做无响应。为了防止这种状况的发生,Android系统定义当应用程序超时无响应时间超过必定时长(界面Activity
默认5秒),会触发应用无响应错误ANR,同时界面弹出提示对话框,以供用户选择退出中止响应或继续等待。因此在生命周期方法内不容许耗时操做。编程
界面Activity
的启动须要经过android.content.Intent意图来操做,意图的建立分显示意图和隐示意图两种类型。顾名思义,显示意图要指定Activity
的具体包名和类名,而隐示意图只须要指定Activity
在清单文件中注册时所嵌入的action和category标签信息。建立的意图做为参数才能启动界面Activity
。显示意图经常使用于当前应用内的界面Activity
之间启动,而隐示意图多用于不一样应用间的界面启动。数据结构
回想下,在Android系统编程入门系列之清单文件文章中说到,主Activity
的注册时,必须在其标签内部嵌入<intent-filter></intent-filter>
标签,并在该标签内固定且惟一<action>
和<category>
标签的内容。这种写法的缘由,就在于Android系统是建立的隐示意图启动应用内的主Activity
。触类旁通,留个问题思考下,若是一个应用的清单文件中有多个上述主Activity
的固定<intent-filter></intent-filter>
标签内容,那Android系统在启动这个应用后会怎么调用这些Activity
呢?(答案将在相应视频教程中揭晓)app
在Android系统经过清单文件找到意图指定的界面Activity
以后,会实例化该界面Activity
对象,并将其放入当前应用程序的指定任务栈中。任务栈,正如其名,是采用先进后出的模式管理当前应用程序启动的全部界面Activity
对象的数据结构。ide
当界面Activity
启动时放入任务栈中,退出界面Activity
时则从任务栈中取出其对象并销毁。然而若是一个应用程序只对应一个任务栈,在有些频繁启动退出单个界面的场景中,就会频繁建立销毁该界面实例,浪费了不少cpu耗时。为了优化界面的实例化过程,Android系统容许一个应用程序使用多个任务栈。这也就引出了两个问题,一是如何从多个任务栈中指定具体一个做为界面启动管理的任务栈?二是界面在启动时放入不一样任务栈的规则是什么?优化
对于第一个问题,在清单文件中静态注册界面Activity
时,能够在<activity></activity>
标签中对属性名taskAffinity赋值,该属性值默认为当前应用包名,从而指定当前界面Activity
所属的任务栈。而<application></application>
标签中也可使用该属性,表示当前应用程序内的全部界面启动时都使用该属性值对应的任务栈管理。同时在界面Activity
中,可使用getTaskId()
来获取当前界面Activity
所属任务栈对应的id值。ui
对于第二个问题,能够根据界面Activity
的启动模式来肯定放入任务栈的规则。启动模式能够在清单文件中静态注册<activity></activity>
标签时,指定其属性launchMode赋值;也能够在建立意图Intent
操做以后,经过调用其setFlags(int flags)
方法动态设置。若是动态设置方式会优先覆盖静态设置方式,若是不设置启动模式,则使用默认模式启动。启动模式主要有四种,其具体方式和对应的属性值可参考下表。google
启动模式 | 静态设置 | 动态设置 | 功能含义 |
---|---|---|---|
标准模式(默认模式) | standard | - | 启动时会在内存空间中实例化对象,并将该对象放入指定任务栈中 |
栈顶单例模式 | singleTop | Intent.FLAG_ACTIVITY_SINGLE_TOP | 启动时先检查指定任务栈顶部界面对象, 若是与该界面信息一致,则使用任务栈顶层的对象; 不然实例化对象并放入指定任务栈顶部 |
栈内单例模式 | singleTask | Intent.FLAG_ACTIVITY_CLEAR_TOP | 启动时检查指定任务栈内的全部界面对象, 若是存在与该界面信息一致的对象,则将其顶部界面对象移出任务栈并销毁,最终保留一致对象在任务栈顶部; 不然实例化对象并放入指定任务栈顶部 |
全局单例模式 | singleInstance | Intent.FLAG_ACTIVITY_NEW_TASK | 启动时检查当前应用程序使用的全部任务栈内的全部界面对象, 若是存在与该界面信息一致的对象,则将其所在任务栈顶部的界面对象移出任务栈并销毁,最终保留一致对象在任务栈顶部; 不然实例化对象并放入指定任务栈顶部 |
attachBaseContext(Context base)
)加载运行环境与Application
同样,Activity
也继承自android.content.ContentWrapper
,使用时绑定上下文环境,尤其注意的是,在AndroidSDK定义的全部android.content.ContentWrapper
子类中,只有android.content.Activity
类中重写了attachBaseContext(Context base)
方法。故界面Activity
实例化以后,系统会最终调用android.content.Activity.attachBaseContext(Context base)
方法,在该方法中以完成将当前界面与上下文环境绑定的任务。线程
一样的,在界面Activity
加载运行环境阶段,也不推荐重写该方法,界面内全部的操做都应在该方法以后完成。
onCreate()
)界面建立在界面加载运行环境以后,Android系统对界面的建立工做就完成了。以后系统回调onCreate()
方法,官方称之为已建立状态。此时当前Activity
还处在后台未展现给用户,所以能够重写该方法,以完成界面内相关变量的初始化操做。
onStart()
)界面展现在界面建立以后,或界面从新展现以后,系统会回调onStart()
方法,将当前Activity
绘制给用户可见,官方称之为已开始状态。若是重写该方法,能够完成展现给用户的界面初始化操做。
onResume()
)界面运行当界面展现以后,系统会回调onResume()
方法,使得界面能够与用户进行交互,官方称之为已恢复状态。此时系统开始响应该界面内的用户交互,这也代表当前界面Activity
已经处于运行了。
系统调用该生命周期方法后会一直处于界面运行中,直到用户的一些操做改变该界面的状态。这些用户操做包括但不限于:
Activity
启动另外一个界面Activity
。Activity
,返回上一个界面Activity
。Application
切换到后台。Activity
在最近任务栏展现。Application
做为多窗口模式之一显示。Application
在后台休眠。Application
被杀死。onPause()
)当界面运行状态被改变后,系统都会首先调用onPause()
方法,此时系统已中止当前界面Activity
与用户的交互响应操做,官方称之为已暂停状态。能够重写该方法,在其中作释放一些不须要但却很耗电的系统资源,以防止无效持有消耗电量。可是此时该界面仍然对用户可见,因此不建议在该方法内执行耗时的释放操做,以避免给用户带来卡顿的假象。
在该状态以后,Android系统根据以前的用户操做类型判断后续生命周期流程。
操做一、二、三、六、7可能会继续令当前界面Activity
中止展现。
而操做四、5将可能在用户从新点击该界面返回,此时将从新回到界面运行的生命周期中。
onStop()
)当系统令当前界面Activiy
中止展现时,会调用onStop()
方法,将当前界面对用户不可见,官方称之为已中止状态。重写该方法时,能够释放界面资源和不须要的CPU耗时资源,以供其余地方及时得到。
在该状态以后,Android系统继续根据以前的用户操做类型判断后续的生命周期流程。
操做1会将新启动的界面Activity
放入当前Activity
所在任务栈中,等待新启动的界面返回时,令当前界面从新展现。
操做2则是将当前界面从任务栈中取出并销毁。
操做3则可能在手机内存不足时,将当前应用的全部界面包括当前界面从任务栈中取出并销毁。
操做6会将当前应用休眠,等设备从新亮屏后,令当前界面从新展现;也可能有的设备在息屏休眠后保持低消耗电源模式时,当前应用超过必定时间或内存占用的休眠期后,被系统杀死,即当前应用的全部界面包括当前界面从任务栈汇总取出并销毁。
操做7则会将当前应用的全部界面所有销毁,不会再调用当前界面的任何生命周期。
onRestart()
)当界面由用户不可见转为可见时,若是以前已经界面建立了,则会调用onRestart()
方法,以代表当前界面将会从新展现。重写该方法能够处理对用户从新可见后的操做。
该方法调用以后,系统将会继续调用界面展现和运行,以从新运行界面与用户的交互操做。
onDestroy()
)当界面Activity
被移除任务栈后,若是应用程序还处在Android系统的控制下,系统将在调用onDestroy()
方法以后销毁界面,官方称之为已销毁状态。重写此方法能够释放全部不须要的资源,以防止发生内存泄漏OOM的问题。
上述内容是针对单个界面Activity
的加载流程,那么其中涉及到的两个界面Activity
的相互交流方式是怎样的,以及界面运行以后如何处理与用户的交互操做?详情请关注后续文章。