activity生命周期和启动模式

在正常情况下生命周期如下:

onCreate:表示生命周期在被创建,这是第一个生命周期,在这里可以做一些初始化的操作,比如:setContentView加载布局。 但是不能在这个方法中获取子控件的大小

onRestart:表示activity被重新启动

onStart:表示activity正在被启动,activity可见,但是不能交互,

onResume:表示activity可见,可以进行人机交互,于onStart的区别在于,onStart还在后台,而onResume在前台。

onPause:失去焦点,失去交互。

onStop : 不可见状态,退回到后台

onDestory :销毁activity,这里可以做一些回收工作,资源释放

生命周期图


1. 第一次启动,调用过程: onCreate - > onStart -> onResume.

2.当打开新的Activity或者切换到桌面的时候:onPause -> onStop , 有一种特殊的情况是:当用户设置了透明的主题,那么当前Activity不会走onStop方法。

3. 当用户再次回到原Activity时,回调如下:onRestart -> onStart ->onResume

4. 当用户按下back键,回调: onPause -> onStop ->onDestory


这里提出两个疑问:

1. onStart、onResume、onStop、onPause从描述上看是差不多的,对我们来说有什么本质的区别呢?

onStart和onStop是从是否可见这个角度来讲的,onResume和onPause 是从与用户是否可以交互这个角度讲的。

2. 当前的Activity 为A,当打开Actiivty B,那么是B的onResume和A的onPause那个先执行呢?

从源码中可以看出,当一个新的Activity要启动时,位于栈顶顶Activity需要先onPause后,新的Activity才能启动。


一般我们不要在onPause中作耗时的操作,以便新的Activity能快速的启动。


异常情况下的生命周期

1. 当资源等系统配置内存不足杀死了Activity然后又重新创建。

当手机从横屏切换到竖屏的时候,当前的Activity会销毁然后重新创建,当然我们也可以阻止横竖屏切换销毁Activity。

当系统配置改变后,Activity重新创建,它所走的生命周期方法是:



当系统以外被杀死后,正常的生命周期方法都会调用,onPause、onStop、onDestory会被调用,还会调用onSaveInstanceState方法保存当前的状态,它调用的时机是在onStop之前。当被重新创建的时候,会调用onRestoreInstanceState方法,将参数保存到Bundle中传递, 在onCreate方法中这个Bundle对象,如果是正常启动这里的Bundle的值是null。如果在onCreate方法中获取参数值,需要进行判空处理,而在onRestoreInstanceState方法中不需要,因为一旦调用这个方法,Bundle中就一定有值。

源码中每一个View都有这两个方法,onSaveInstanceState和onRestoreInstanceState方法。首先Activity以为终止,会调用onSaveInstanceState方法去保存数据。然后Activity会委托Window去保存数据,Window会委托它的顶级容器去保存数据,一般是ViewGroup,或者DecorView,最后顶级容器通知它的子元素去保存数据。这就是一个典型的委托思想,它与java虚拟机加载class字节码文件的委托加载机制的思想是一样的。源码中可以看到,view保存了一些状态和内容。


不想让Activity在屏幕旋转的时候重新创建,可以在清单文件中设置configChanges属性添加orientation这个值:

android:configChanges="orientation|screenSize"





启动模式

Activity launchMode有四种启动模式:standard、singleTop、singleTask、singleInstance。

1. standard标准模式,这是系统默认的模式,每次启动activity都会创建的一个新的activity。谁启动了这个Actiivty,那么这个activity就会在启动它的那个任务栈中。比如Activity A启动了Activity B,那么这个B就会进入到A所在到任务栈中。

但是当我们使用ApplicationContext启动standard模式的activity就会报错,因为非Activity类型的context并没有所谓的任务栈,只有Activity 才有任务栈。解决办法就是在为启动的Activity指定任务栈:

FLAG_ACTIVITY_NEW_TASK
这样就创建了一个新的任务栈,这个时候启动的Activity实际上是以singleTask模式启动的。


singleTop:栈顶复用模式。在这个模式下,如果新的Activity已经位于栈顶,那么就不会再创建新的Activity。同时会调用它的onNewIntent方法。这里的onCreate方法和onStart方法不会被调用。如果新的Activity实例存在但是不位于栈顶,那么会创建一个新的Activity实例。


singleTask:栈内复用模式,这是一个相当于单例模式,只要Activity实例存在,那么多次启动Activity都不会重新创建Activity。同时它也会调用onNewIntent()方法。它会将启动的activity栈上边的其他Activity实例全部出栈 ,将这个activity实例放到栈顶。


singleInstance:单实例模式,它单独启用一个任务栈。这个任务栈中只有这一个实例。


singleTask中什么是需要的任务栈呢?

这要从一个参数说起:TaskAffity ,这个参数标记了activity所需要的任务栈名字。默认情况下,所有的任务栈的名字是应用包名。指定新的任务栈不能和包名一样。


给Activity指定启动模式有两种方式:

第一种是在ActivityMenifest中设置

android:launceMode="singleTast"
第二种是:在Intent中设置标志位。

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

区别在于第二种方式的优先级比第一种高,当两种方式都存在,以第二种方式为准。



IntentFilter匹配

Actiivity启动分为显示启动和隐式启动。隐式启动需要设置匹配规则,这个匹配组建就是IntentFilter ,它有三个可以提供过滤的,action、data、category。一个Intent必须完全匹配过滤规则才能隐式启动Activity。一个Activity可以包含多个intent-filter,一个Intent只要能匹配任何一组intent-filter就可以启动Activity。

action规则:action是一个字符串,一个过滤规则中可以有多个action,只要一个可以匹配就行。它区分大小写,一个过滤规则中必须包含action,否则无法匹配。

category规则:过滤规则中可以不设置category,它与action 不同,action是必须设置的,而category可以不设置,如果设置了,那么必须匹配上,否则报错。

data规则:data由两部分组成,mimeType和URI 。mineType指媒体类型,比如:image/jpeg、audio/mpeg4-generic和video/*等。

URI结构为:

<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]

scheme:表示URI的模式:有http/file/content 等,如果没有设置scheme,那么整个uri无效。

host:主机名。

port:当指定scheme和host后,这个端口才有效。

path等三个都是指定路径。

如果要为intent指定完整的data,必须调用setDataAndType方法,不能先调用setData,然后再调用setType。因为这两个方法会彼此清除对方的值。






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Activity启动模式是Android应用程序中非常重要的概念,它决定了Activity启动方式和生命周期的管理方式。在Android中,Activity启动模式主要有以下几种: 1. standard:标准模式。默认情况下,每次启动Activity时都会创建一个新实例,并放入任务栈中。如果该Activity已经存在任务栈中,则会将该Activity放到栈顶,并重新调用其onCreate()方法。 2. singleTop:栈顶复用模式。如果新启动Activity已经存在任务栈的栈顶,则不会创建新实例,而是将已有的实例作为当前任务的Activity,并调用其onNewIntent()方法。如果新启动Activity不在栈顶,则会创建新实例,并将其放到任务栈的栈顶。 3. singleTask:栈内复用模式。如果新启动Activity已经存在任务栈中,则不会创建新实例,而是将已有的实例作为当前任务的Activity,并将其上面的Activity全部出栈,调用其onNewIntent()方法。如果新启动Activity不存在任务栈中,则会创建新实例,并放到任务栈的栈顶。 4. singleInstance:单例模式。在一个新的任务栈中创建Activity,并且该任务栈中只有该Activity实例。如果该Activity已经存在于其他任务栈中,则会将该任务栈中的该Activity实例移动到新的任务栈中。 下面是Activity的源码分析: 1. standard模式Activity的源码中,标准模式是默认的启动模式。当我们使用startActivity()方法启动一个Activity时,会调用ActivityStackSupervisor类中的startActivityLocked()方法。在该方法中,会通过ActivityStack类的findTaskLocked()方法查找是否存在当前Activity所在的任务栈。如果存在,则会将当前Activity放到该任务栈的栈顶,并调用其onCreate()方法。如果不存在,则会创建一个新的任务栈,并将当前Activity放到该任务栈的栈顶。 2. singleTop模式 当我们在Manifest文件中设置Activity启动模式为singleTop时,会在ActivityInfo中保存该信息。在ActivityStackSupervisor类的startActivityLocked()方法中,会通过ActivityStack类的findTaskLocked()方法查找是否存在当前Activity所在的任务栈,并判断当前Activity是否在栈顶。如果在栈顶,则会调用其onNewIntent()方法。如果不在栈顶,则会创建一个新的实例,并放到该任务栈的栈顶。 3. singleTask模式 当我们在Manifest文件中设置Activity启动模式为singleTask时,会在ActivityInfo中保存该信息。在ActivityStackSupervisor类的startActivityLocked()方法中,会通过ActivityStack类的findTaskLocked()方法查找是否存在当前Activity所在的任务栈。如果存在,则会找到该任务栈中的栈顶Activity,并将其上面的所有Activity出栈。然后将当前Activity放到该任务栈的栈顶,并调用其onNewIntent()方法。如果不存在,则会创建一个新的任务栈,并将当前Activity放到该任务栈的栈顶。 4. singleInstance模式 当我们在Manifest文件中设置Activity启动模式为singleInstance时,会在ActivityInfo中保存该信息。在ActivityStackSupervisor类的startActivityLocked()方法中,会创建一个新的任务栈,并将当前Activity放到该任务栈的栈顶。如果该Activity已经存在于其他任务栈中,则会将该任务栈中的该Activity实例移动到新的任务栈中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值