关于Activity
引用google官方文档,是这么说的:
Activity
是一个应用组件,用户可与其提供的屏幕进行交互,以执行拨打电话、拍摄照片、发送电子邮件或查看地图等操作。 每个 Activity 都会获得一个用于绘制其用户界面的窗口。窗口通常会充满屏幕,但也可小于屏幕并浮动在其他窗口之上。
Activity是整个应用的基础,也是最基本的组件,一个应用通常由多个彼此松散联系的 Activity 组成。
关于Activity,我们需要了解以下几部分内容:
1.生命周期
关于生命周期,涉及的方法主要有下面七个:
onCreate()
首次创建 Activity 时调用。 您应该在此方法中执行所有正常的静态设置 — 创建视图、将数据绑定到列表等等。 系统向此方法传递一个 Bundle 对象,其中包含 Activity 的上一状态(前提是捕获了该状态)。始终后接 onStart()。
onRestart()
当前Activity已经创建,但是处于后台不可见状态(onStop已经执行),再次启动时调用。始终后接 onStart()。
与其他方法不同的是,onRestart()在整个生命周期中不是必定执行的方法。
onStart()
在 Activity 即将对用户可见之前调用。
如果 Activity 转入前台,则后接 onResume(),如果 Activity 转入隐藏状态,则后接 onStop()
onResume()
在 Activity 即将开始与用户进行交互之前调用。 此时,Activity 处于 Activity 堆栈的顶层,并具有用户输入焦点。
始终后接 onPause()。
onPause()
当系统即将开始继续另一个 Activity 时调用。 此方法通常用于确认对持久性数据的未保存更改、停止动画以及其他可能消耗 CPU 的内容,诸如此类。 它应该非常迅速地执行所需操作,因为它返回后,下一个 Activity 才能继续执行。
如果 Activity 返回前台,则后接 onResume(),如果 Activity 转入对用户不可见状态,则后接 onStop()。
onStop()
在 Activity 彻底对用户不可见的时候调用。
如果 Activity 恢复与用户的交互,则后接 onRestart(),如果 Activity 被销毁,则后接 onDestroy()。
onDestroy()
在 Activity 被销毁前调用。这是 Activity 将收到的最后调用。 当 Activity 结束(有人对 Activity 调用了 finish()
),或系统为节省空间而暂时销毁该 Activity 实例时,可能会调用它。 您可以通过isFinishing() 方法区分这两种情形。
因此,按照Activity的状态,生命周期分为三个部分,完整周期(onCreate到onDestroy),可见周期(onStart到onStop),前台周期(onResume到onPause)。系统会根据Activity所处的状态来决定调用的方法。
2.保存Activity状态
当 Activity 暂停或停止时,Activity 的状态会得到保留,是如何操作的呢?主要用到这个方法:
onSaveInstanceState()
那么,什么时候会调用该方法?简言之,在Activity即将处于可能被销毁的状态时(非用户主动销毁,比如按下back键)。按下home键,电源键,启动新的Activity以及横竖屏切换等。
该方法调用一定在onStop之前,可能在onPause之前。
调用该方法的时候,系统会向此方法传递一个Bundle,用来保存重要的数据,以便重建的时候恢复状态。在重建Activity时,该Bundle会传递给onCreate和onRestoreInstanceState,可以在这两个方法中恢复状态。
onRestoreInstanceState()
该方法调用时处于Create和Start之后,除非Activity确实被销毁了,重建时才会调用该方法,否则不会调用。
另外,横竖屏切换的时候有些特殊,默认情况下,横竖屏切换时,当前Activity会销毁然后重建。
也就是说,执行顺序会是这样子:
Pause→SaveInstanceState→Stop→Destroy→Create→Start→RestoreInstanceState→Resume
这里会涉及一个configuration的概念。在manifest文件里可以配置Activity的属性:
android:configChanges="orientation|screenSize"
此时切换横竖屏,Activity不会销毁,只会调用onConfigurationChanged方法。
3.任务和返回栈
应用通常包含多个Activity,当一个Activity被启动时,如果当前不存在任务,系统会创建新的任务,并将该Activity作为根Activity存在返回栈中,新的Activity启动时,会放在该Activity之上,处于栈顶位置,栈顶的Activity作为用户焦点。当back键按下时,栈顶的Activity被销毁出栈,下一个Activity推到栈顶位置。
应当注意的是,每个Activity会有一个taskAffinity属性,默认情况下,一个应用中所有的Activity都具有相同的taskAffinity,也就是说,所有Activity会被存放在同一个任务中,哪怕当前应用调用了其他应用的Activity。
如果想将Activity存放到新的任务中,采用以下步骤:
1.给intent添加一个NEW_TASK的flag
2.manifest中指定Activity的taskAffinity(通常值为某应用的包名)
除此之外,Activity还有一个allowTaskReparenting的属性。从字面可以这么理解,允许重新分配父任务。当设置它为true的时候,会出现这种情况:
A应用启动了B应用的一个Activity1,此时Activity1会处于A应用的任务栈中,这时候启动B应用,奇怪的事情发生了,B应用出现的不是启动界面,而是Activity1。因为,B应用创建了自己的任务栈之后,会将Activity1从A的栈中转移过来,所以显示的是Activity1。
4.启动模式
四种启动模式相信大家都耳熟能详了:
standard(默认模式)
Activity启动一次,就会生成一个新的实例,并添加到返回栈的顶部。
singleTop
如果当前栈顶位置已经有该Activity的实例,那么,系统只会调用onNewIntent方法,向其传送intent,不会生成新的实例。
如果当前栈顶位置不是该Activity,那么,不管该栈中是够有该Activity的其他实例,都会在栈顶生成新的Activity。
singleTask
任务栈中只允许有一个该Activity的实例。如果没有,生成一个,如果已有该Activity的实例,将该实例之上的Activity出栈,系统只会调用onNewIntent方法,向其传送intent,不会生成新的实例。
singleInstance
生成该Activity的实例,并将其放入单独的返回栈中,该栈中不允许存放其他的Activity。
如果之前已经生成该Activity的实例。那么,系统只会调用onNewIntent方法,向其传送intent,不会生成新的实例。
注意:除了standard模式,其他三个都存在调用onNewIntent的情况。
5.启动Activity以及参数传递
startActivity,通过intent传递参数就不多说了。详细说一下startActivityForResult:
此方法用在希望从启动的Activity获取返回结果的情况下。
相关方法:
startActivityForResult(Intent intent, Int requestCode)
setResut(int resultCode, Intent intent)
onActivityResult(int requestCode, int resultCode, Intent intent)
Activity A启动Activity B,并希望传回结果时,操作方法如下:
A用startActivityForResult来启动B,requestCode用来判断传回的结果(取值>=0)。因为一个Activity中可能有许多onActivityResult,所以必须设置requestCode用来识别传回的结果是来自哪一个Activity
B中用setResult来填入希望返回的值,resultCode设置为RESULT_OK,Intent用来携带传回的值
A中重写回调方法onActivityResult 根据requestCode来获取想要的结果。
值得一提的是,setResult应该在什么时候调用呢?
因为Activity被finish的时候才会把结果传回去,所以,setResult应该在被Activity被finish之前调用。
其他
Activity的属性及其意义,点击这里.
常用方法:
onBackPressed:按下back键时调用的方法
finish():销毁Activity