Android 启动模式

一直对activity的启动模式和种种Flag意识模模糊糊,抽空详细研究了下,这里做一个记录,防止自己再遗忘。

Activity的加载模式

Android的Activity启动模式有四种

  • standard

    标准模式,一般没有设置launchMode的情况下默认是该模式。

    05-09 13:56:02.668 21785-21785/com.hj.intentdemo D/>>>>>>>MainActivity: onCreate: 
    05-09 13:56:02.674 21785-21785/com.hj.intentdemo D/>>>>>>>MainActivity: onResume: 
    05-09 13:56:05.906 21785-21785/com.hj.intentdemo D/>>>>>>>MainActivity: onPause: 
    05-09 13:56:05.942 21785-21785/com.hj.intentdemo D/>>>>>>>EActivity: onCreate: 
    05-09 13:56:05.947 21785-21785/com.hj.intentdemo D/>>>>>>>EActivity: onResume: 
    05-09 13:56:06.298 21785-21785/com.hj.intentdemo D/>>>>>>>MainActivity: onStop: 
    05-09 13:56:24.570 21785-21785/com.hj.intentdemo D/>>>>>>>EActivity: onPause: 
    05-09 13:56:24.598 21785-21785/com.hj.intentdemo D/>>>>>>>EActivity: onCreate: 
    05-09 13:56:24.601 21785-21785/com.hj.intentdemo D/>>>>>>>EActivity: onResume: 
    05-09 13:56:24.952 21785-21785/com.hj.intentdemo D/>>>>>>>EActivity: onStop: 
    

    在Mainactivity中启动EActivity,在EActivity启动EActivity的生命周期Log。注意跳转到新Activity时,旧Activity的生命周期,先是执行了MainActivity的onPause(),再执行Eactivity的onCreate()、onResume(),之后执行了MainActivity的onStop()。具体原因可以Google或者查看源码,此处不在多说。

  • singleTop

    基本和标准模式相同,只有当当前需要跳转的Activity刚好处于栈顶时才不重新创建实例。设置EActivity启动模式为singleTop

    05-09 16:00:30.239 16289-16289/com.hj.intentdemo D/>>>>>>>MainActivity: onCreate: 
    05-09 16:00:30.240 16289-16289/com.hj.intentdemo D/>>>>>>>MainActivity: onResume: 
    05-09 16:00:50.544 16289-16289/com.hj.intentdemo D/>>>>>>>MainActivity: onPause: 
    05-09 16:00:50.625 16289-16289/com.hj.intentdemo D/>>>>>>>EActivity: onCreate: 
    05-09 16:00:50.626 16289-16289/com.hj.intentdemo D/>>>>>>>EActivity: onResume: 
    05-09 16:00:51.063 16289-16289/com.hj.intentdemo D/>>>>>>>MainActivity: onStop: 
    05-09 16:00:59.707 16289-16289/com.hj.intentdemo D/>>>>>>>EActivity: onPause: 
    05-09 16:00:59.707 16289-16289/com.hj.intentdemo D/>>>>>>>EActivity: onResume: 
    

    上面是在MainActivity的直接跳转到EActivity中,EActivity跳转到Eactivity执行的生命周期Log

    05-09 16:03:45.482 18404-18404/com.hj.intentdemo D/>>>>>>>MainActivity: onCreate: 
    05-09 16:03:45.483 18404-18404/com.hj.intentdemo D/>>>>>>>MainActivity: onResume: 
    05-09 16:03:48.467 18404-18404/com.hj.intentdemo D/>>>>>>>MainActivity: onPause: 
    05-09 16:03:48.503 18404-18404/com.hj.intentdemo D/>>>>>>>EActivity: onCreate: 
    05-09 16:03:48.504 18404-18404/com.hj.intentdemo D/>>>>>>>EActivity: onResume: 
    05-09 16:03:48.929 18404-18404/com.hj.intentdemo D/>>>>>>>MainActivity: onStop: 
    05-09 16:03:53.966 18404-18404/com.hj.intentdemo D/>>>>>>>EActivity: onPause: 
    05-09 16:03:53.987 18404-18404/com.hj.intentdemo D/>>>>>>>AActivity: onCreate: 
    05-09 16:03:53.987 18404-18404/com.hj.intentdemo D/>>>>>>>AActivity: onResume: 
    05-09 16:03:54.457 18404-18404/com.hj.intentdemo D/>>>>>>>EActivity: onStop: 
    05-09 16:03:57.983 18404-18404/com.hj.intentdemo D/>>>>>>>AActivity: onPause: 
    05-09 16:03:58.022 18404-18404/com.hj.intentdemo D/>>>>>>>EActivity: onCreate: 
    05-09 16:03:58.022 18404-18404/com.hj.intentdemo D/>>>>>>>EActivity: onResume: 
    05-09 16:03:58.426 18404-18404/com.hj.intentdemo D/>>>>>>>AActivity: onStop: 
    

    上面执行顺序为MainActivity—>EActivity—>AActivity—>EActivity

  • singleTask

    当前activity栈中是否存在activity实例,存在发送intent到activity中,不存在则在新栈中创建新Activity实例

    先来看生命周期

    05-10 14:58:48.228 4474-4474/com.hj.intentdemo D/>>>>>>>DActivity: onPause: 
    05-10 14:58:48.267 4474-4474/com.hj.intentdemo D/>>>>>>>EActivity: onCreate: 
    05-10 14:58:48.267 4474-4474/com.hj.intentdemo D/>>>>>>>EActivity: onResume: 
    05-10 14:58:48.679 4474-4474/com.hj.intentdemo D/>>>>>>>DActivity: onStop: 
    05-10 14:58:50.570 4474-4474/com.hj.intentdemo D/>>>>>>>BActivity: onDestroy: 
    05-10 14:58:50.578 4474-4474/com.hj.intentdemo D/>>>>>>>CActivity: onDestroy: 
    05-10 14:58:50.584 4474-4474/com.hj.intentdemo D/>>>>>>>DActivity: onDestroy: 
    05-10 14:58:50.588 4474-4474/com.hj.intentdemo D/>>>>>>>EActivity: onPause: 
    05-10 14:58:50.593 4474-4474/com.hj.intentdemo D/>>>>>>>AActivity: onResume: 
    05-10 14:58:50.958 4474-4474/com.hj.intentdemo D/>>>>>>>EActivity: onStop: 
    05-10 14:58:50.958 4474-4474/com.hj.intentdemo D/>>>>>>>EActivity: onDestroy: 
    

    依次由MainActivity—>Activity(singleTAsk)—>BActivity—>CActivity—>DActivity—>EActivity—>AActivity 当由E跳转到A时,销毁了A之前的B、C、D,之后A执行onResume()。和设置intent Falg为FLAG_ACTIVITY_CLEAR_TOP|FLAG_ACTIVITY_SINGLE_TOP效果相同。你可能会想不是应该创建新的栈,为什么任务管理器中仍然看到一个,想要实现这种效果你可以加上android:taskAffinity=""这个属性,上图

    Android 启动模式_第1张图片

  • singleInstance

    这个基本和singleTask相同,唯一的区别就是在这个模式下Activity实例所处的task栈中,只能有这么一个Activity实例,不能再有其他实例。一旦该模式的activity的实例已经存在于某个栈中,任何应用在激活该activity时都会重用该栈中的实例。

    还是老方法,图片加Log生命周期走起

    Android 启动模式_第2张图片
    05-10 15:40:13.526 7364-7364/com.hj.intentdemo D/>>>>>>>MainActivity: onCreate: 
    05-10 15:40:13.536 7364-7364/com.hj.intentdemo D/>>>>>>>MainActivity: onResume: 
    05-10 15:40:14.940 7364-7364/com.hj.intentdemo D/>>>>>>>MainActivity: onPause: 
    05-10 15:40:14.967 7364-7364/com.hj.intentdemo D/>>>>>>>AActivity: onCreate: 
    05-10 15:40:14.971 7364-7364/com.hj.intentdemo D/>>>>>>>AActivity: onResume: 
    05-10 15:40:15.390 7364-7364/com.hj.intentdemo D/>>>>>>>MainActivity: onStop: 
    05-10 15:40:15.830 7364-7364/com.hj.intentdemo D/>>>>>>>AActivity: onPause: 
    05-10 15:40:15.857 7364-7364/com.hj.intentdemo D/>>>>>>>BActivity: onCreate: 
    05-10 15:40:15.860 7364-7364/com.hj.intentdemo D/>>>>>>>BActivity: onResume: 
    05-10 15:40:16.266 7364-7364/com.hj.intentdemo D/>>>>>>>AActivity: onStop: 
    05-10 15:40:20.461 7364-7364/com.hj.intentdemo D/>>>>>>>BActivity: onPause: 
    05-10 15:40:20.495 7364-7364/com.hj.intentdemo D/>>>>>>>CActivity: onCreate: 
    05-10 15:40:20.500 7364-7364/com.hj.intentdemo D/>>>>>>>CActivity: onResume: 
    05-10 15:40:20.898 7364-7364/com.hj.intentdemo D/>>>>>>>BActivity: onStop: 
    05-10 15:40:23.069 7364-7364/com.hj.intentdemo D/>>>>>>>CActivity: onPause: 
    05-10 15:40:23.360 7364-7364/com.hj.intentdemo D/>>>>>>>CActivity: onStop: 
    05-10 15:40:26.948 7364-7364/com.hj.intentdemo D/>>>>>>>CActivity: onResume: 
    05-10 15:40:28.769 7364-7364/com.hj.intentdemo D/>>>>>>>CActivity: onPause: 
    05-10 15:40:29.270 7364-7364/com.hj.intentdemo D/>>>>>>>CActivity: onStop: 
    05-10 15:40:29.270 7364-7364/com.hj.intentdemo D/>>>>>>>CActivity: onDestroy: 
    
    

    启动顺序为MainActivity—>AActivity(singleTask)—>BActivity(singleTask)—>CActivity。CActivity没有设置taskAffinity属性,默认是和MainActivity处于同一Task中。

    多任务管理器直跳转到CActivity,back键返回。直接到主界面了,并没有出现MainActivity。生命周期也没有出现MainActivity被结束的生命周期,重新点击启动app,生命周期中出现了MainActivity的onResume()。

核心特性

  • taskAffinity
  • launchMode
  • allowTaskReparenting
  • clearTaskOnLaunch
  • alwaysRetainTaskState
  • finishOnTaskLaunch

Intent Flag

核心Flag约有三个:

  • FLAG_ACTIVITY_NEW_TASK
  • FLAG_ACTIVITY_CLEAR_TOP
  • FLAG_ACTIVITY_SINGLE_TOP

常用Flag

  • FLAG_ACTIVITY_BROUGHT_TO_FRONT

    效果和启动模式的singleTask一样

  • FLAG_ACTIVITY_CLEAR_TOP

    Task中包含A、B、C、D。D启动B,Task为A、B。下面是跳转过程中Activity生命周期的log

    05-09 17:07:50.622 13590-13590/com.hj.intentdemo D/>>>>>>>MainActivity: onCreate: 
    05-09 17:07:50.623 13590-13590/com.hj.intentdemo D/>>>>>>>MainActivity: onResume: 
    05-09 17:07:56.066 13590-13590/com.hj.intentdemo D/>>>>>>>MainActivity: onPause: 
    05-09 17:07:56.113 13590-13590/com.hj.intentdemo D/>>>>>>>AActivity: onCreate: 
    05-09 17:07:56.114 13590-13590/com.hj.intentdemo D/>>>>>>>AActivity: onResume: 
    05-09 17:07:56.560 13590-13590/com.hj.intentdemo D/>>>>>>>MainActivity: onStop: 
    05-09 17:08:00.333 13590-13590/com.hj.intentdemo D/>>>>>>>AActivity: onPause: 
    05-09 17:08:00.359 13590-13590/com.hj.intentdemo D/>>>>>>>BActivity: onCreate: 
    05-09 17:08:00.359 13590-13590/com.hj.intentdemo D/>>>>>>>BActivity: onResume: 
    05-09 17:08:00.768 13590-13590/com.hj.intentdemo D/>>>>>>>AActivity: onStop: 
    05-09 17:08:03.945 13590-13590/com.hj.intentdemo D/>>>>>>>BActivity: onPause: 
    05-09 17:08:03.980 13590-13590/com.hj.intentdemo D/>>>>>>>CActivity: onCreate: 
    05-09 17:08:03.981 13590-13590/com.hj.intentdemo D/>>>>>>>CActivity: onResume: 
    05-09 17:08:04.371 13590-13590/com.hj.intentdemo D/>>>>>>>BActivity: onStop: 
    05-09 17:08:06.294 13590-13590/com.hj.intentdemo D/>>>>>>>CActivity: onPause: 
    05-09 17:08:06.312 13590-13590/com.hj.intentdemo D/>>>>>>>DActivity: onCreate: 
    05-09 17:08:06.313 13590-13590/com.hj.intentdemo D/>>>>>>>DActivity: onResume: 
    05-09 17:08:06.738 13590-13590/com.hj.intentdemo D/>>>>>>>CActivity: onStop: 
    05-09 17:08:15.773 13590-13590/com.hj.intentdemo D/>>>>>>>CActivity: onDestroy: 
    05-09 17:08:15.814 13590-13590/com.hj.intentdemo D/>>>>>>>DActivity: onPause: 
    05-09 17:08:15.824 13590-13590/com.hj.intentdemo D/>>>>>>>BActivity: onDestroy: 
    05-09 17:08:15.849 13590-13590/com.hj.intentdemo D/>>>>>>>BActivity: onCreate: 
    05-09 17:08:15.849 13590-13590/com.hj.intentdemo D/>>>>>>>BActivity: onResume: 
    05-09 17:08:16.248 13590-13590/com.hj.intentdemo D/>>>>>>>DActivity: onStop: 
    05-09 17:08:16.248 13590-13590/com.hj.intentdemo D/>>>>>>>DActivity: onDestroy: 
    

    从生命周期中可以看出,D跳转到B时,会销毁C之后销毁B重新创建,再销毁D。有兴趣的可以直接跳转到A,观察B和C的生命周期情况。

    你可能会想到,如何能让B不创建直接跳转呢?可以设置B的launchMode为singleTop或者跳转时设置Flag为FLAG_ACTIVITY_CLEAR_TOP时同时设定为FLAG_ACTIVITY_SINGLE_TOP

    intent.setFlags(FLAG_ACTIVITY_CLEAR_TOP|FLAG_ACTIVITY_SINGLE_TOP);
    

    这样就可以不创建B的实例,B的生命周期应该会只执行onResume()

    05-09 17:18:33.516 20964-20964/com.hj.intentdemo D/>>>>>>>CActivity: onPause: 
    05-09 17:18:33.544 20964-20964/com.hj.intentdemo D/>>>>>>>DActivity: onCreate: 
    05-09 17:18:33.544 20964-20964/com.hj.intentdemo D/>>>>>>>DActivity: onResume: 
    05-09 17:18:33.978 20964-20964/com.hj.intentdemo D/>>>>>>>CActivity: onStop: 
    05-09 17:18:34.446 20964-20964/com.hj.intentdemo D/>>>>>>>CActivity: onDestroy: 
    05-09 17:18:34.462 20964-20964/com.hj.intentdemo D/>>>>>>>DActivity: onPause: 
    05-09 17:18:34.478 20964-20964/com.hj.intentdemo D/>>>>>>>BActivity: onResume: 
    05-09 17:18:34.887 20964-20964/com.hj.intentdemo D/>>>>>>>DActivity: onStop: 
    05-09 17:18:34.887 20964-20964/com.hj.intentdemo D/>>>>>>>DActivity: onDestroy: 
    

    上面部分生命周期(从C跳转D开始)可以看出,D跳转到B时,销毁了C、D,B只执行了onResume()和我们猜想的相同。

    该模式还可以和FLAG_ACTIVITY_NEW_TASK结合使用,用于启动一个Task中的根Activity,它会把那个Task中任何运行的实例带入前台,然后清除它直到根Activity。这非常有用,例如,当你要从Notification Manager处启动一个Activity,就需要设置为该Flag。

  • FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET

    设置该种Flag时,会在Activity栈中加入“还原点”,当直接点击home退出到主界面后再回来时并不会回到栈顶Activity,此时会清除Task中设置为“还原点”的Activity及其之上的所有Activity。

    直接上log,下面依次由A—>B—>C(设置为FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)—>D—>E的部分生命周期(在E按下home键)

    05-09 17:53:37.468 32462-32462/com.hj.intentdemo D/>>>>>>>EActivity: onPause: 
    05-09 17:53:38.039 32462-32462/com.hj.intentdemo D/>>>>>>>EActivity: onStop: 
    05-09 17:53:49.457 32462-32462/com.hj.intentdemo D/>>>>>>>CActivity: onDestroy: 
    05-09 17:53:49.521 32462-32462/com.hj.intentdemo D/>>>>>>>DActivity: onDestroy: 
    05-09 17:53:49.558 32462-32462/com.hj.intentdemo D/>>>>>>>EActivity: onDestroy: 
    05-09 17:53:49.563 32462-32462/com.hj.intentdemo D/>>>>>>>BActivity: onResume: 
    

    E进入后台时执行onPause()、onStop(),再次进入前台时,销毁了“还原点”(C之上包含C)之前的所有Activity。

  • FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

    设置了该Flag,启动的Activity就不会出现在最近任务列表中。这样说可能很抽象,直接上图

    Android 启动模式_第3张图片
    Android 启动模式_第4张图片

    上图代码区分就是设置与否intent.setFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);你也可以在Mainfest下Activity标签加上android:excludeFromRecents =“true”属性就可以达到相同的效果。设置Flag可以让开发者使用已发布的app功能时使其不存在于应用列表下。当然你也可以设置你的launcherActivity为该属性就可以使你的程序不在最近任务列表了。这样你就可以放心开发不可描述的应用了[奸笑]

  • FLAG_ACTIVITY_NEW_TASK

    在新的Task中启动Activity,需要配合android:taskAffinity=""属性一块使用,才能达到单独任务列表

  • FLAG_ACTIVITY_NO_ANIMATION

    设置该Flag,Activity切换时不会产生动画效果

  • FLAG_ACTIVITY_NO_HISTORY

    Activity不会留在Task栈中,用户一旦离开即销毁Activity。下面是启动MainActivity—>AActivity。切换到后台后重新回来的生命周期

    05-11 01:14:44.545 10514-10514/com.hj.intentdemo D/>>>>>>>MainActivity: onCreate: 
    05-11 01:14:44.547 10514-10514/com.hj.intentdemo D/>>>>>>>MainActivity: onResume: 
    05-11 01:14:46.039 10514-10514/com.hj.intentdemo D/>>>>>>>MainActivity: onPause: 
    05-11 01:14:46.053 10514-10514/com.hj.intentdemo D/>>>>>>>AActivity: onCreate: 
    05-11 01:14:46.054 10514-10514/com.hj.intentdemo D/>>>>>>>AActivity: onResume: 
    05-11 01:14:46.524 10514-10514/com.hj.intentdemo D/>>>>>>>MainActivity: onStop: 
    05-11 01:14:48.757 10514-10514/com.hj.intentdemo D/>>>>>>>AActivity: onPause: 
    05-11 01:14:49.262 10514-10514/com.hj.intentdemo D/>>>>>>>AActivity: onStop: 
    05-11 01:14:53.225 10514-10514/com.hj.intentdemo D/>>>>>>>MainActivity: onResume: 
    05-11 01:14:53.226 10514-10514/com.hj.intentdemo D/>>>>>>>AActivity: onDestroy: 
    

    可以清晰的看出,当重新回到前台时,MainActivity进入onResume(),AActivity被销毁了

  • FLAG_ACTIVITY_REORDER_TO_FRONT

    设置该Flag,会将已经创建的Activity移动到Task的顶端,下面还是先来看下生命周期log

    05-11 03:06:52.018 3038-3038/com.hj.intentdemo D/>>>>>>>MainActivity: onCreate: 
    05-11 03:06:52.034 3038-3038/com.hj.intentdemo D/>>>>>>>MainActivity: onResume: 
    05-11 03:06:54.443 3038-3038/com.hj.intentdemo D/>>>>>>>MainActivity: onPause: 
    05-11 03:06:54.469 3038-3038/com.hj.intentdemo D/>>>>>>>AActivity: onCreate: 
    05-11 03:06:54.471 3038-3038/com.hj.intentdemo D/>>>>>>>AActivity: onResume: 
    05-11 03:06:55.169 3038-3038/com.hj.intentdemo D/>>>>>>>MainActivity: onStop: 
    05-11 03:06:55.772 3038-3038/com.hj.intentdemo D/>>>>>>>AActivity: onPause: 
    05-11 03:06:55.785 3038-3038/com.hj.intentdemo D/>>>>>>>BActivity: onCreate: 
    05-11 03:06:55.786 3038-3038/com.hj.intentdemo D/>>>>>>>BActivity: onResume: 
    05-11 03:06:56.391 3038-3038/com.hj.intentdemo D/>>>>>>>AActivity: onStop: 
    05-11 03:06:56.963 3038-3038/com.hj.intentdemo D/>>>>>>>BActivity: onPause: 
    05-11 03:06:56.988 3038-3038/com.hj.intentdemo D/>>>>>>>CActivity: onCreate: 
    05-11 03:06:56.988 3038-3038/com.hj.intentdemo D/>>>>>>>CActivity: onResume: 
    05-11 03:06:57.641 3038-3038/com.hj.intentdemo D/>>>>>>>BActivity: onStop: 
    05-11 03:06:58.251 3038-3038/com.hj.intentdemo D/>>>>>>>CActivity: onPause: 
    05-11 03:06:58.260 3038-3038/com.hj.intentdemo D/>>>>>>>AActivity: onResume: 
    05-11 03:06:58.956 3038-3038/com.hj.intentdemo D/>>>>>>>CActivity: onStop: 
    

    启动顺序为MainActivity—>AActivity—>BActivity—>CActivity—>AActivity。我们可以看出,当重新启动AActivity时,只是重新调整了Task。可以理解为和FLAG_ACTIVITY_CLEAR_TOP效果相反。

  • FLAG_ACTIVITY_SINGLE_TOP

    设置了该Flag,当启动的Activity处于栈顶则不创建新的Activity实例。

注意:如果是从BroadcastReceiver启动一个新的Activity,或者是从Service往一个Activity跳转时,不要忘记添加Intent的Flag为FLAG_ACTIVITY_NEW_TASK。

你可能感兴趣的:(Android 启动模式)