Activity不同情况下生命周期

想要彻底弄清楚Activity在不同情况下的生命周期需要先掌握Activity的一些基础知识

Activity完整的生命周期如下图:

生命周期流程图
知道了Activity完整的生命周期之后还需要知道Activity的启动模式。

Activity四种启动模式:

  • standard:
    默认的启动模式,每次通过这种模式启动目标Acitivity,都创建一个新的实例,并将该Activity添加到当前栈顶。

  • singleTop:
    只有当Activity位于栈顶时,系统才不会重新创建目标Activity的实例,而是直接复用已有的Activity实例。否则创建一个新的实例。这种模式经常被用在新闻展示页,当推送过来一条新闻,跳转到新闻页显示,如果你正在看新闻,就不需要重复的创建这个activity

  • singleTask:
    如果栈中不存在目标Activity时,则创建目标Activity实例。
    如果栈中存在目标Activity时,
    (1)已经位于栈顶,此时与singleTop行为相同
    (2)不位于栈顶,系统会使该Activity上面所有的Activity出栈。

  • singleInstance:
    如果栈中不存在目标Activity,系统会创建一个新的任务栈,再创建Activity实例,将它加入该栈中
    如果栈中存在该Activity,无论哪个应用程序调用,都不会创建新的Activity

举例

假设有两个Activity A、B

  1. standard模式
    当A启动到从A跳转到B的生命周期
    A启动时:onCreate -> onStart -> onResume
    从A跳转到B时:A.onPause -> B.onCreate -> onStart -> onResume -> A.onStop
    按back键返回时:B.onPause -> A.onReStart -> onStart -> onResume -> B.onStop -> onDestroy
  2. singleTop模式
    设定A为singleTop,启动A,从A跳A,就是在栈顶时会不会创建A的实例
    A启动时:onCreate -> onStart -> onResume
    从A跳A时:onPause -> onResume
    按back键返回时:onPause -> onStop -> onDestroy
    可以看到并没有重新创建A的实例,只是执行了onPause 和onResume
  3. singleTask模式
    设定A为singleTask,启动A,从A跳B,再从B跳A
    A启动时:onCreate -> onStart -> onResume
    从A跳转到B时:A.onPause -> B.onCreate -> onStart -> onResume -> A.onStop
    从B跳转到A时:B.onPause -> A.onReStart -> onStart -> onResume -> B.onStop -> onDestroy
    可以看到当A在栈中存在时,再次跳转不会创建A的实例并使A上面的B出栈
  4. singleInstance模式
    为 singleInstance 模式时,activity独占一个task,现在有以下三个activity: Act1、Act2、Act3,其中Acti2 为 singleInstance 模式。它们之间的跳转关系为: Act1 – Act2 – Act3 ,现在在Act3中按下返回键,由于Act2位于一个独立的task中,它不属于Act3的上下文activity,所以此时将直接返回到Act1,Act1再按下返回键时到Act2,这就是singleInstance模式。

看完四种模式,这里会有疑问:

为什么要先执行A的onPause方法,再执行B的生命周期方法?
为什么不是执行完A的onStop方法之后再执行B的生命周期方法?

首先来看第一个问题,假如A正在播放一段音乐,如果先执行B的生命周期,再执行A的onPause方法,就会出现B已经显示出来,A中的音乐还在播放的异常情况。而如果先执行了A的onPause方法,我们就可以在其中执行一些操作来暂停音乐的播放。原本onPause方法的设计职责即使如此。
对于第二个问题,由于Activity的可见生命周期是onStart()到onStop(),假如先执行A的onPause()和onStop(),再执行B的生命周期,每次切换的时候就会出现黑屏的情况,这种切换效果显然是不优雅的。

注:

  • 建议在onCreate()中调用setContentView()、findViewById()
  • 建议在onResume()中打开独占设备(比如相机)、开启动画等
  • 建议在onPause()中执行关闭独占设备、停止动画等比较耗CPU的操作,但不要执行比较耗时的操作,底层执行Activity的onPause()时,有一定的时间限制的,当ActivityManagerService通知应用进程暂停指定的Activity时,如果对应的onPause()在500ms内还没有执行完,ActivityManagerService就会强制关闭这个Activity。
  • onStop()中可以执行一些比较耗时的操作,这是在后台执行所以也不影响用户的体验

附:
伴随着activity常用的除了生命周期还有两个方法,onSaveInstanceState 和 onNewIntent

1.onSaveInstanceState
我们都知道不同的手机,内存不同,系统在内存不足的时候很有可能就会把你APP中不再栈顶的activity给回收掉。如果这个activity无关紧要那就啥也不说了,但是就怕它对你来说很重要。这个时候你不对它进行保护措施的话,你就等着哭吧。比如你打开了A,A是一个注册类activity。然后你填写了一堆信息后,返回桌面去看了一条短信,或者接了一个电话,等你再打开这个的时候你发现里面填写的东西都不见了,这个时候你想不想一巴掌拍死这个开发人员?

所以呢onsaveinstancestate()就可以闪亮登场了,虽然你也可以使用其他保存机制去处理,但是对于这种情况,onsaveinstancestate()依然是最佳的选择。onsaveinstancestate()方法有的同学有可能没见过 但是savedinstancestate相必都见过,就是在oncreate()方法的那个括号里面,savedinstancestate是一个bundle类型的参数,bundle有很多保存数据的方法这个你想必是知道的吧,对我们就是利用这个去保存数据。onsaveinstancestate()回调方法会保证一定在activity被回收之前调用

onSaveInstanceState方法会在什么时候被执行,有这么几种情况:

  • 当用户按下HOME键时。
  • 长按HOME键,选择运行其他的程序时。
  • 按下电源按键(关闭屏幕显示)时。
  • 从activity A中启动一个新的activity时。
  • 屏幕方向切换时,例如从竖屏切换到横屏时。

当按下HOME键或者锁屏时,会执行onPause -> onSaveInstanceState -> onStop
当从activity A跳转到 B 时,A.onPause -> B.onCreate -> onStart -> onResume -> A.onSaveInstanceState -> A.onStop

使用:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_one);
        if (savedInstanceState != null) {
            String oldString = savedInstanceState.getString("Activity");
            Log.e(TAG,"oldString="+oldString);
        }
        Log.e(TAG,"onCreate");
    }

@Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.e(TAG,"onSaveInstanceState");
        String string = "activity 被系统回收了怎么办?";
        outState.putString("Activity", string);
    }

2.onNewIntent
如果activity设置为singleTask或者signleTop模式【当调用startActivity方法时,这两种模式不会重新创建activity,只会调用onNewIntent方法,当然任务栈中没有销毁该activity的情况下】,再向activity传值时,就可以利用onNewIntent
执行顺序:onNewIntent -> onReStart -> onStart -> onResume

@Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.e(TAG,"onNewIntent");
        setIntent(intent);
        String msg = getIntent().getExtras().getString("msg");
        Log.e(TAG,"msg="+msg);
    }

//另一个activity中发送
 Intent intent = new Intent(this,OneActivity.class);
 intent.putExtra("msg","传值过来");
 startActivity(intent);

猜你喜欢

转载自blog.csdn.net/zyw0101/article/details/80043826