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

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

singleTop模式

设定A为singleTop,启动A,从A跳A,就是在栈顶时会不会创建A的实例

A启动时:onCreate -> onStart -> onResume

从A跳A时:onPause -> onResume

按back键返回时:onPause -> onStop -> onDestroy

可以看到并没有重新创建A的实例,只是执行了onPause 和onResume

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出栈

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);

---------------------

你可能感兴趣的:(Activity不同情况下生命周期)