无冥冥之志者,无昭昭之明;无惛惛之事者,无赫赫之功。
 解释:没有专心致志地刻苦学习,就没有融会贯通的智慧;没有埋头执着的工作,就不会取得显著的成就。

Activity生命周期及启动模式

   Activity是Android的基础,四大组件之一,也是面试中基本上都会被问到的内容。基本上面试问的点都是他的生命周期及启动模式。以下对面试中经常被问到的点进行总结:

Activity的生命周期方法有哪些?

   这个就很简单了,onCreate->onStart->onResume->onPause->onStop->onDestroy。

生命周期的各个方法可以干什么?

  • onCreate: 第一次创建Activity的时候调用,进行Activity的一些初始化工作,调用setContentView方法加载布局。
  • onStart: 表示启动,此方法调用之后,Activity可见但是不可交互
  • onResume: 此时Activity可以交互
  • onPause: Activity可见但是不可交互,可以释放系统资源,比如传感器、摄像头等
  • onStop: Activity已不可见,可以做一些停止动画、数据存储、资源回收工作
  • onDestroy: Activity被销毁之前最后一个回调方法,已经不可见,可以做一些资源回收工作

Activity启动模式有哪些?

   Activity的启动模式跟Task有关。这里先理清Task和回退栈的关系。Android官方文档给出的解释是:Task是用户完成某项工作时,与之互动的一系列的Activity的集合。看到这就知道了Task和回退栈的关系,以前一直以为Task是一个栈,回退栈又是另一个栈。其实是Task是跟用户交互的一系列Activity的集合,而这个集合用栈的形式表现,它们是一回事。以后就统称Task栈了。

   启动一个应用的时候,会创建一个默认Task,这个Task用来记录用户与这个应用交互的时候启动Activity的顺序。不过,这些Activity使用不同的启动模式,可能会改变它们在回退栈中的顺序,也有可能使得系统会新建一个Task来存放它们。

  • standard:标准模式,每次新启动都会在Task栈中创建一个实例。
  • singleTop:栈顶复用模式,每次这种模式的Activity被启动时,先查看Task栈顶是否是被启动的Activity的实例,如果不是就创建实例,然后压入Task栈。如果是则调用onNewIntent方法服用这个实例。不用在调用onCreate创建
  • singleTask:栈内复用模式,每次这种模式的Activity被启动时,先查看Task栈内是否有该Activity的实例,如果有,则将栈内处于该Task栈上方的Activity出栈(会调用出栈Activity的onDestroy方法),复用栈内的实例,然后调用onNewIntent方法。如果没有,则创建实例。
  • singleInstance:单例模式,这种模式的Activity会分配一个单独的Task栈。每次这种模式的Activity被启动时,会查看是否为这个Activity分配了Task栈,如果有则复用,否则新创建一个Task栈,再创建该Activity的实例。

Activity启动模式配置方式有哪些?有什么区别?

   Activity的启动方式有两种,一种是在manifest文件中通过配置Activity的属性launchMode中设置。另一种是在代码中调用startActivity是设置的参数Intent中设置。两种方式的区别是:第一种是设置的默认启动方式,第二种是指定启动方式。当两种都设置的时候,以第二种为准。比如Activity A在manifest文件中设置的启动模式是:standard,这个时候在Activity B中通过startActivity方法启动Activity A,并且参数Intent调用setFlags方法设置了Intent.FLAG_ACTIVITY_CLEAR_TOP,这个时候Activity A的启动模式就是按照setFlags方法设置的模式启动。

可以指定一个Activity在哪个Task栈启动吗?怎么配置?

   可以。这种情况下,需要设置Activity的taskAffinity属性。 想要指定Activity在指定的Task中启动,需要的设置:1、在manifest文件中给对应的Activity的taskAffinity属性设置一个值(注意这个值需要带一个“.”,不然会报错);2、设置这个Activity的launchMode = singleTask或者调用startActivity的时候参数Intent调用setFlags,使用参数FLAG_ACTIVITY_NEW_TASK。

Activity的生命周期和启动模式联合询问

比如:启动模式是singleTask的Activity A启动singleInstance模式的Activity的生命周期过程是怎么样的?

   答:首先是Activity A的生命周期的onCreate,onStart,onResume方法被调用,然后点击按钮启动Activity B,这时候先调用Activity A的onPause方法暂停Activity A,接着调用Activity B的onCreate,onStart,onResume方法将Activity B显示出来,接着调用Activity A的onStop方法。

再来一个。Activity A启动模式是standard,Activity B的启动模式singletask,Activity C的启动模式是singleInstance。启动顺序:A -> B -> C -> A -> B -> C。

他们之间的生命周期方法顺序:

  • Activity A: onCreate -> onStart -> onResume -> onPause
  • Activity B: onCreate -> onStart -> onResume
  • Activity A: onStop
  • Activity B: onPause
  • Activity C: onCreate -> onStart -> onResume
  • Activity B: onStop
  • Activity C: onPause
  • Activity A: onCreate -> onStart -> onResume (Activity A调用onCreate重新创建实例)
  • Actiivty C: onStop
  • Activity A: onPause
  • Activity B: onRestart -> onStart -> onNewIntent -> onResume (Activity B复用栈中实例,不调用onCreate重新创建实例)
  • Activity A: onStop -> onDestroy (Activity B要复用,Activity A就要被退出栈,接着被销毁)
  • Activity B: onPause
  • Activity C: onRestart -> onStart -> onNewIntent -> onResume(Activity C不重新创建实例)
  • Activity B: onStop

   上面三个Activity,Activity A、Activity B将存放在同一个Task栈,而Activity C拥有一个独立的Task栈。

跨应用启动Activity情况下,Activity启动模式和Task栈的情况

   当前有两个应用,App 1,App 2。

   App 1的Activity A启动App 2的Activity B。注意App 2的启动Activity不是Activity B,而是Activity C。

   Activity A的启动模式是standard、singleTop、singleTask,Activity B的启动模式是的standard、singleTop情况下,Activity A和Activity B同属于一个Task栈,也就是Activity A所在的Task栈。这个时候,返回桌面启动App 2,也就是启动App 2的启动Activity C,这个时候会新建一个Task栈给App 2,将Activity C的实例压入栈,这时候点击Activity C页面的按钮启动ActivityB,会发现ActivityB会重新创建一个实例压入Activity C所在的Task栈中。

   Activity B的启动模式是singleTask的情况下,会创建一个新的Task栈,并创建Activity B的实例,将这个实例压入新的栈。这个时候,返回桌面启动App 2的时候,就绕过了Activity C直接(复用)启动了Activity B,挺有意思的一个现象。

   针对上述Activity B的启动模式是singleTask的情况下,出现的现象。可以给Activity B的taskAffinity属性设置一个值(注意这个值需要带“.”),这样做之后,仍然会创建一个Task栈压入Activity B实例。但是当启动App 2的时候,就不会饶过Activity C了,仍然会创建一个Task栈压入Activity C的实例。如果Activity B有一个按钮用于启动Activity D,这时候不论Activity B是否设置taskAffinity属性,启动Activity D的时候,Activity D都会跟Activity B在一个Task栈。

   Activity A的启动模式是sIngleInstance,Activity B的启动模式是的standard、singleTop、singleTask情况下,Activity B不会和Activity A,在同一个Task任务栈中,也不在App 1的其他Task栈中,而是在一个新建的Task栈中。这个时候,返回桌面,启动App 2的时候,还是会绕过Activity C,直接启动Activity B。

   不管ActivityA的启动模式是什么,Activity B的启动模式是singleInstance的情况下,也会创建新的Task栈,将Activity B的实例压入栈,这个栈将作为Activity B独有的Task栈。这个时候,返回桌面启动App 2的时候,会新建一个Task栈,将Activity C的实例压入栈,这时候点击Activity C页面的按钮启动ActivityB,因为Activity B有一个独享的Task栈,将不会重新创建Activity B的实例。

results matching ""

    No results matching ""