美文网首页
Activity不同情况下生命周期

Activity不同情况下生命周期

作者: 那年的歌 | 来源:发表于2019-05-27 10:31 被阅读0次

    想要彻底弄清楚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不同情况下生命周期

          本文链接:https://www.haomeiwen.com/subject/ksectctx.html