Activity是Android系统中的四大组件之一,其主要功能是提供与用户交互的界面。
1.Activity栈
Android采用Task来管理多个Activity,当我们启动一个应用时,Activity就会为之创建一个Task,然后启动这个应用的入口Activity(即intent-filter中配置为MAIN和LAUNCHER的Activity)。我们可以把Task理解为Activity栈,其保存了已经启动并且还没有终止的所有的Activity,并且我们知道栈是遵从“后进先出”的规则,那么Activity栈同样也遵从这样的规则。
Activity 的状态与其在Activity栈的位置有着密切的关系。不仅如此,Android系统在资源不足时,也是通过Activity栈来选择哪些 Activity是可以被终止的,一般来讲,Activity系统会优先选择终止或者目前处于停止状态并且比较靠近Activity栈底的Activity。
2.Activity的几种状态
(1)活动(Active)状态:此时Activity处于栈顶,并且是可见的,有焦点,能够接收用户输入并给予响应。当另一个Activity变成Active时,当前的将变成Paused状态。
(2)暂停(Paused)状态:此时Activity是可见的,但是没有焦点时。例如前面的Activity是全透明或非全屏幕的Activity时,其下面的Activity就处于Paused状态。当处于Paused状态时,该Activity仍被认为是Active的,但是它不接受用户输入事件。当一个Activity完全被遮住时,它将进入Stopped状态。
(3)停止(Stopped)状态:此时Activity不可见,处于Stopped状态。但是,该Activity将继续保留在内存中保持当前的所有状态和成员信息,假设系统别的地方需要内存的话,这时它是被回收对象的主要候选。当Activity处于Stopped状态时,一定要保存当前数据和当前的UI状态,否则一 旦Activity退出或关闭时,当前的数据和UI状态就丢失了。
(4)非活动(Inactive)状态:Activity被杀掉以后或者被启动以前,处于Inactive状态。这时Activity已被从Activity栈中移除,需要重新启动才可以显示和使用。
3.Activity生命周期
(1)onCreate(Bundle saveInstanceState)
该方法在Activity第一次启动时调用,且启动后就不在执行,除非由于系统内存紧张,把处于Paused和Stopped状态下的Activity回收,然后再重新启动。形式参数saveInstanceState,主要保存Activity由于系统内存不足等原因,被系统隐式销毁Activity,在被销毁之前一般的会调用onSaveInstanceState(),保留该Activity此时的状态信息。
(2)onStart()
一般情况下,该方法是在onCreate()之后调用或者在Stopped状态返回时调用。
(3)onResume()
Activity启动过程执行onCreate()—>onStart()—>onResume(),或者当Activity处于Paused状态时onPause()—>onResume()
(4)onPause()
Activity被切换到后台时执行onPause(),一般在onPause()中保存永久性数据。
(5)onStop()
Activity被切换到后台并且不可见时,onPause()—>onStop()。
(6)onRestart()
onStop()执行之后,该Activity和进程没有被系统销毁,此时用户又重新返回该Activity,则会执行Activity的onRestart()—>onStart()
(7)onDestroy()
Activity被销毁时执行onDestroy()。
4.Activity四种加载模式
配置Activity时可以指定android:launchMode属性,用于配置Activity的加载模式
(1)standard:标准模式(始终创建新实例)
启动目标Activity时,总会为该Activity创建一个新的实例,并放入当前Task的栈顶。
(2)singleTop:单顶模式(如果栈顶已有实例则不再创建新实例)
启动目标Activity时,若已经有一个目标Activity位于栈顶,则不会创建新的目标Activity实例,而是复用原有的;若没有目标Activity位于栈顶,则会创建一个新的目标Activity实例,并放入当前Task的栈顶。
(3)singleTask:单任务栈模式(保持Task内只有一个该目标Activity实例)
启动目标Activity时,若当前Task内不存在目标Activity实例,则会创建一个新的目标Activity实例,并放入当前Task的栈顶;若已经有一个目标Activity实例位于栈顶,则不会创建新的目标Activity实例,而是复用原有的;若当前Task内已经有一个目标Activity实例,但不位于栈顶,则会移除该实例上面的所有Activity,从而使该实例位于栈顶。
(4)singleInstance:单例模式(保持所有Task内只有一个该目标Activity实例,且用一个单独的Task栈放这个实例)
启动目标Activity时,若目标Activity的实例不存在,则会创建一个全新的Task,再创建一个该目标Activity的实例,并将其放入新Task的栈顶;若已经存在目标Activity的实例,则会将该实例所在的Task转到前台。
5.启动(跳转)和关闭Activity
Activity的跳转需要创建Intent对象,通过设置Intent对象的参数指定要跳转Activity
(1)显式跳转(通过设置Activity的包名和类名实现跳转)
(2)隐式跳转(通过指定动作实现跳转)
当然,要让一个Activity可以被隐式启动,需要在AndroidManifest.xml文件的activity节点中设置intent-filter子节点
(3)startActivityForResult
假设有两个Activity,分别是A和B,A跳转至B,B执行完一系列操作后需要将结果返回A,此时就需要使用 startActivityForResult()来启动B了。
具体分为3个步骤:
a)A跳转B的时候不采用startActivity(intent) 方法,而是采用startActivityForResult(intent, Int requestCode)方法,requestCode可以是大于等于0的任何值。
b)在A中重写onActivityResult方法,用来接收B回传的数据,根据传回来的resultCode做相应的逻辑处理。
c)在B中采用setResut(int resultCode, Intent intent)方法,并且之后要调用finish方法。
6.Activity之间数据传递
Activity之间数据传递通过使用Bundle数据携带包来实现,Bundle对象分别有存和取的方法。
putXXX(String key,Xxx data):向Bundle对象中放入int、String等各种类型的数据
getXXX(String key):从Bundle对象中取出int、String等各种类型的数据
当然,我们可以直接调用intent对象的putExtra(String key,XXX data)方法存入数据,但其本质还是创建或使用了Bundle对象进行传值。