Activity知识点

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shu_lance/article/details/79945965

Activity的知识点主要有:

  1. 生命周期(正常与异常);
  2. 启动模式(Launcher Mode);
  3. 隐式启动(IntentFilter与action、category、data);

一、Activity的生命周期:

1. 正常的生命周期(七个方法):

先附上正常的生命周期流程:

image

  1. 正常情况下,一个Activity所经历的生命周期是:onCreate()->onStart()->onResume()->onPause()->onStop()->onDestory();除此之外,还有一个onRestart(),这个将在后面讲到;
  2. onCreate():当Activity第一次创建的时候会被调用(注意:一个Activity是不能被new出来的,因为Activity是基于组件的设计模式,需要在Android工程环境中才能正常地运行,此时有一个核心的功能类Context);在onCreate()这个方法中,我们可以做一些初始化工作,比如:调用setContentView()去加载界面布局资源(但是此时只是加界面布局资源addView到DecorView中,并不是真正地绘制布局,真正绘制是在onResume的时候),初始化Activity所需要的数据;当然onCreate()方法中参数有一个Bundle对象,可以用来恢复异常情况下Activity结束时的状态(此时涉及到Activity的异常生命周期);
  3. onStart():表示Activity正在被启动,即将开始,这是Activity已经出现,但是还没有出现在前台(处于后台),无法与用户交互;此时我们可以理解为此时的Activity已经显示出来,但是我们还是看不到;
  4. onResume():表示Activity已经可见,并且出现在前台并开始活动;需要和onStart()对比,onStart()的时候Activity还在后台,onResume()的时候Activity才显示到前台,布局资源的绘制是在onResume()的时候才开始绘制的;
  5. onPause():表示Activity正在停止(暂停),但是仍可见,正常情况下,onStop会被调用;但在特殊情况下(比如:在singleTop启动模式下启动栈顶的Activity的时候,会调用onNewIntent()),如果这个时候快速地回到当前的Activity,那么Activity的onResume就会被调用;在onPause中不能执行耗时操作,因为会影响到新的Activity的启动;因为onPause执行完,新的Activity的onResume才会执行;可以做一些重要数据的轻量型保存;
  6. onStop():表示Activity即将停止,不可见,位于后台;可以做稍微重量级的回收工作,但是不能太耗时;
  7. onDestroy():表示Activity即将销毁,这是Activity生命周期的最后一个回调,可以做一些资源的回收,比如:gc回收工作等等;
  8. onReStart():表示Activity正在重新启动,一般情况下,当当前的Activity从不可见变为可见的时候,onRestart就会被调用,这种情形一般是由用户导致的,比如:当我们按Home键回到主界面的时候,或者打开一个Activity后,按back健返回之前的Activity(都是onPause()->onStop()->onRestart()->onStart()->onResume());
生命周期的几种情况:
  1. 第一次启动Activity时:onCreate()->onStart()->onResume();
  2. 用户打开新的Activity时:(旧)onPause() -> (新)onCreate() -> (新)onStart() -> (新)onResume() -> (旧)onStop();
  3. 再次回到旧Activity时(按下back健):(新)onPause() -> (旧)onRestart() -> (旧)onStart() -> (旧)onResume() -> (新)onStop() -> (新)onDestory();
  4. 按下back健:onPause() -> onStop() -> onDestory();
  5. 按下Home健回到主界面,再次返回到该Activity的时候:onPause() -> onStop() -> onRestart() -> onStart() -> onResume();
  6. 调用finish()方法时:onPause() -> onStop() -> onDestory();
  7. 当Activity弹出一个普通的Dialog时:onResume()
  8. 当Activity弹出一个Activity样式的Dialog时:onResume() -> onPause();当该Dialog退出后:onPause() -> onResume();
  9. 当启动一个透明的Activity的时候:(旧)onPause() -> (新)onCreate() -> (新)onStart() -> (新)onResume(); 当此时按下back健时:(新)onPause() -> (旧)onResume() -> (新)onStop() -> (新)onDestory();
2. 特殊情况下的生命周期:

上面介绍了正常情况下的生命周期,接下来介绍一下特殊情况下的生命周期,主要有两种特殊的生命周期:1. 横竖屏切换;2. 资源内存不足导致优先级低的Activity被杀死

1. 横竖屏切换
  1. 在横竖屏切换过程中,会发生Activity被销毁并重建的过程;
  2. 特殊情况下的生命周期会涉及到这个回调:onSaveInstanceState()onRestoreInstanceState();

    • onSaveInstanceState:在Activity由于异常情况下终止时,系统会调用onSaveInstanceState()来保存当前的Activity的状态,这个方法是在onStop之前调用的,在onPause前后要看情况(横竖屏切换时,该方法在onPause之后,在onStop之前),并且把Activity销毁时onSaveInstanceState方法所保存的Bundle对象参数传递给onRestoreInstanceState和onCreate方法

    • onRestoreInstanceState:因此,可以通过onRestoreInstanceState来恢复Activity的状态,该方法的调用是在onStart之后;其中onCreate和onRestoreInstanceState方法来恢复Activity是有区别的:onRestoreInstanceState回调则表明该Bundle对象一定是非空的;而onCreate需要进行判断是否为空;一般建议使用onRestoreInstanceState;

    • 横竖屏切换时: (旧)onResume() -> (旧)onPause() -> (旧)onSaveInstanceState() -> (旧)onStop() -> (旧)onDestory() -> (新)onCreate() -> (新)onStart() -> (新)onRestoreInstanceState() -> (新)onResume() ;

image

  • 如果想避免横竖屏切换时,Activity的销毁和重建,我们可以在AndroidManifest中设定Activity的configChanges属性:
android:configChanges = "orientation| screenSize"

回调了onConfigurationChanged方法:

@Override
public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
    }
2. 当资源不足的时候导致优先级低的Activity被杀死:

Activity的优先级可以划分为:
1. 前台Activity——正在与用户交互的Activity,优先级最高;
2. 可见但非前台Activity——比如弹出一个对话框,此时的Activity处于后台但是可见,无法与用户进行交互;
3. 后台Activity——已经被停止的Activity,比如执行了onStop,优先级最低;

Activity的三种运行状态:
  1. Resumed(活动状态):此时的Activity正在屏幕上显示,并且可以与用户进行交互;
  2. Paused(暂停状态):比较不常见的状态,此时Activity是可见的,但并不是处于前台的;比如:一个非全屏或者透明的Activity是Resumed的时候,没有完全遮盖这个Activity;
  3. Stopped(停止状态)当Activity完全不可见时,此时的Activity处于后台,仍在内存中保留着状态,并没有销毁;比如:当我启动一个新的Activity的时候,之前的Activity处于后台,当我们按下Back键的时候,之前的Activity就会恢复原来的状态;

二、启动模式(Launcher Mode):

  • Android提供了四种启动方式:
    1.standard 标准模式;
    2.singleTop 栈顶复用模式;
    3.singleTask 栈内复用模式;
    4.singleInstance 单例模式;

  • 启动模式的数据结构——栈:

Activity的管理是采用任务栈的形式,任务栈采用“后进先出” 的栈结构;

image

  • Activity的LauncherMode:

1.标准模式(standard):每次启动一个Activity的时候,都会创建一个新的Activity的实例并置于栈顶;谁启动了这个新的Activity,该Activity就会处于那个Activity所处的栈中;

image

  • 特殊情况下:如果Service或者Application启动一个Activity的时候,此时并没有所谓的任务栈,为了解决这个问题,我们可以为待启动的Activity指定一个FLAG_ACTIVITY_NEW_TASK标记位,创建一个任务栈;

2.栈顶复用模式(singleTop):如果新建的Activity位于任务栈的栈顶,此时Activity就不需要被创建,而是复用栈顶的Activity,回调onNewIntent方法;如果该Activity不处于栈顶,则会创建该Activity的新实例,置于栈顶;

  • 应用场景:在通知栏点击通知的时候,启动Activity,此时使用singleTop模式,可以避免多次点击,创建多个Activity;

3.栈内复用模式(singleTask):该模式是一种单例模式,即一个任务栈内只能有一个Activity实例;在该模式下,可以在AndroidManifest文件中指定能够该Activity加载到哪个任务栈中(此时需要singleTask与taskAffinity配合使用,指定Activity加载到哪个任务栈);

  • taskAffinity:每个Activity都有taskAffinity这个属性,这个属性指出该Activity需要被加载到哪个任务栈内;如果没有显性指明该Activity的taskAffinity,那么这个值等于Application指明的taskAffinity,如果Application的taskAffinity也没有指明,那么该taskAffinity的值等于包名;

  • 该模式下的执行过程:启动一个Activity,如果该Activity指定的栈不存在,则创建一个任务栈,并把该Activity置于栈顶;如果该任务栈存在,但Activity不在该栈中,则创建Activity置于栈顶;如果栈存在且Activity处于栈中,则把Activity上面的所有Activity销毁并清除,重用Activity置于栈顶,并回调onNewIntent方法;

  • 应用场景:大多数的APP的主页,我们都是在主界面时,按下back键才退出APP,因此,我们不管打开了多少个Activity,只要我们回到主界面,主界面上的所有Activity都应被销毁,让主界面的Activity处于栈顶,而不是往栈顶添加一个新的主界面的Activity,所以退出应用时,所有的Activity都会被销毁;

4.单例模式(singleInstance):栈内复用模式的加强版,打开一个新的Activity的时候,直接创建一个新的任务栈,并创建该Activity实例放入新的任务栈内;一旦该模式的Activity实例已经处于某个栈内,任何应用激活该Activity时都会重用该栈内的实例;

  • 应用场景:呼叫来电界面;这种模式比较罕见,比较少用到;
4. Activity的Flags:
  • Activity中的Flags有很多,比如:

1.FLAG_ACTIVITY_NEW_TASK:效果与指定了singleTask启动模式的效果一样;
2.FLAG_ACTIVITY_SINGLE_TOP:效果与指定了singleTop的效果一样;
3.FLAG_ACTIVITY_CLEAR_TOP:具有此标记位的Activity,当启动时,在同一个任务栈中所有位于它上面的Activity都要出栈;

如果与singleTask模式结合使用:若被启动的Activity已经存在于栈中,则清除其上的所有Activity,并使该Activity置于栈顶,并调用onNewIntent方法;
如果与Standard模式结合使用:,那么该Activity与其上的所有Activity都会出栈,然后重新创建一个新的该Activity实例压入栈中;

IntentFilter匹配规则

  • Activity的启动可以分为两种:显示调用、隐式调用;

1.显示调用:需要明确指定被启动对象的组件信息,包括包名与类名;
2.隐式调用:需要Intent能够匹配目标组件的IntentFilter中所设置的匹配规则(过滤信息);过滤信息有:action、category、data;只有一个Intent同时匹配action、category、data才算完全匹配,只有完全匹配才能成功启动Activity;

1. action(行为):

1.action是一个字符串,系统预定义了一些action,同时我们也可以在应用中定义自己的action;
2.匹配规则:Intent中的action必须能够和过滤规则中的action匹配,这里匹配是指字符串值完全一样;
3.一个过滤规则中有多个action,只要Intent中action能够和过滤规则的任何一个action相同就可匹配成功;即要求Intent中的action存在且必须和过滤规则中的其中一个action相同;

2. category(类别):

1.匹配规则:要求Intent中如果含有category,那么所有的category都必须和过滤规则中的其中一个category相同;换句话说,Intent中如果出现了category,那么不管有几个category,对于每个category来说,必须是过滤规则中已经定义了的category;
2.category与action的不同:action是要求Intent中必须有一个action必须能够和过滤规则中的某个action相同,而category要求Intent中可以没有category,但一旦拥有,不管有几个,每个都要能够和过滤规则中的任何一个相同;
3.category可以有,也可以不设置,不设置的时候,调用startActivity或者startActivityForResult的时候会默认为Intent加上DEFAULT这个category;同时,为了使activity能够隐式调用,就必须在intent-filter中指定DEFAULT这个category

3. data(数据):

1.data的结构稍微有点复杂,就不深究了;但是data的匹配规则与action的匹配规则是类似的;

注意:
  • 当我们隐式调用activity的时候,看是否有Activity能够匹配我们隐式的Intent,判断方法有:
    1.采用PackageManager的resolveActivity方法(还有一个queryIntentActivities,返回所有成功匹配Activity的信息)或者Intent的resolveActivity方法,找不到匹配的Activity就可以返回null,从而可以判断该返回值进行规避错误;
    2.不含有DEFAULT这个category的Activity是不可以接收隐式Intent的
阅读更多
想对作者说点什么? 我来说一句
相关热词

没有更多推荐了,返回首页