面试题一:组件之Activity系列

2019校招Android面试题解1.0(上篇)

目录

Q1:说下Activity的生命周期?

Q2:onStart()和onResume()/onPause()和onStop()的区别?

Q3:Activity A启动另一个Activity B会回调哪些方法?如果Activity B是完全透明呢?如果启动的是一个Dialog呢?

Q4:谈谈onSaveInstanceState()方法?何时会调用?

Q5:onSaveInstanceState()与onPause()的区别?

Q6:如何避免配置改变时Activity重建?

Q7:优先级低的Activity在内存不足被回收后怎样做可以恢复到销毁前状态?

Q8:说下Activity的四种启动模式?(有时会出个实际问题来分析返回栈中Activity的情况)

activity的四种启动模式区别_launchmode图文详解 查看文章

Activity生命周期全解析、四种启动模式、IntentFilter匹配规则;查看文章

a.standard:标准模式、默认模式   [ˈstændərd] 

b.singleTop:栈顶复用模式

c.singleTask:栈内复用模式

d.singleInstance:单实例模式

Q10:onNewIntent()调用时机? 

Q11:了解哪些Activity启动模式的标记位? 

Q12:如何启动其他应用的Activity?  

方式一:用action启动

方式二:用intent设置className或component的办法启动

Q13:Activity的启动过程?


Activity是Android最核心的组件,我们在Activity的XML文件中搭建界面,展示给用户,同时与用户进行交互。

Q1:说下Activity的生命周期?

面试题一:组件之Activity系列_第1张图片

首先了解Activity的四种状态

  • Running状态:一个新的Activity启动入栈后,它在屏幕最前端,处于栈的最顶端,此时它处于可见并可和用户交互的激活状态。
  • Paused状态:当Activity被另一个透明或者Dialog样式的Activity覆盖时的状态。此时它依然与窗口管理器保持连接,系统继续维护其内部状态,它仍然可见,但它已经失去了焦点,故不可与用户交互。
  • Stopped状态:当Activity不可见时,Activity处于Stopped状态。当Activity处于此状态时,一定要保存当前数据和当前的UI状态,否则一旦Activity退出或关闭时,当前的数据和UI状态就丢失了。
  • Killed状态:Activity被杀掉以后或者被启动以前,处于Killed状态。这时Activity已从Activity堆栈中移除,需要重新启动才可以显示和使用。

  4种状态中,Running状态和Paused状态是可见的,Stopped状态和Killed状态时不可见的。

onCreate():

  • 状态:Activity 正在创建
  • 任务:做初始化工作,如setViewContent界面资源、初始化数据
  • 注意:此方法的传参Bundle为该Activity上次被异常情况销毁时保存的状态信息。

onStart():

  • 状态:Activity 正在启动,这时Activity 可见但不在前台,无法和用户交互。

onResume():

  • 状态:Activity 获得焦点,此时Activity 可见且在前台并开始活动。

onPause():

  • 状态: Activity 正在停止
  • 任务:可做 数据存储、停止动画等操作。
  • 注意:Activity切换时,旧Activity的onPause会先执行,然后才会启动新的Activity。

onStop():

  • 状态:Activity 即将停止
  • 任务:可做稍微重量级回收工作,如取消网络连接、注销广播接收器等。
  • 注意:新Activity是透明主题时,旧Activity都不会走onStop。

onDestroy():

  • 状态:Activity 即将销毁
  • 任务:做回收工作、资源释放。

onRestart():

  • 状态:Activity 重新启动,Activity由后台切换到前台,由不可见到可见。

面试题一:组件之Activity系列_第2张图片

不难看出,其实这些方法都是两两对应的,onCreate创建与onDestroy销毁;onStart可见与onStop不可见;onResume可编辑(即焦点)与onPause;这6个方法是相对应的,那么就只剩下一个onRestart方法了,这个方法在什么时候调用呢?答案就是:在Activity被onStop后,但是没有被onDestroy,在再次启动此Activity时就调用onRestart(而不再调用onCreate)方法;如果被onDestroy了,则是调用onCreate方法。

Q2:onStart()和onResume()/onPause()和onStop()的区别?

  • onStart()与onStop()是从Activity是否可见这个角度调用的,onResume()和onPause()是从Activity是否显示在前台这个角度来回调的,在实际使用没其他明显区别。

Q3:Activity A启动另一个Activity B会回调哪些方法?如果Activity B是完全透明呢?如果启动的是一个Dialog呢?

  • A启动B:A的onPause() -->B的onCreate()-->onStart()-->onResume()-->A的onStop()
  • A启动B,B完全透明:A的onPause() -->B的onCreate()-->onStart()-->onResume()
  • A界面启动一个dialog:如果是单纯的一个dialog,并不调用生命周期,如果启动的是一个以dialog形式展示的activity,同上。

Q4:谈谈onSaveInstanceState()方法?何时会调用?

  • a.出现时机:异常 情况下Activity 重建,非用户主动去销毁
  • b.系统异常终止时,调用onSavaInstanceState来保存状态。该方法调用在onStop之前,但和onPause没有时序关系。
  • c.Activity被重新创建时,调用onRestoreInstanceState(该方法在onStart之后),并将onSavaInstanceState保存的Bundle对象作为参数传到onRestoreInstanceState与onCreate方法。

Q5:onSaveInstanceState()与onPause()的区别?

  • 前者适用于对临时性状态的保存,而后者适用于对数据的持久化保存。

Q6:如何避免配置改变时Activity重建?

  • 如果不手动配置Activity configChanges属性,系统默认对Activity进行销毁重建操作。
  • API13以下,Activity configChanges属性中含有orientation即可避免Activity销毁重建。
  • API13及以上,Activity configChanges属性中同时含有orientation和screenSize即可避免Activity销毁重建。

Q7:优先级低的Activity在内存不足被回收后怎样做可以恢复到销毁前状态?


Q8:说下Activity的四种启动模式?(有时会出个实际问题来分析返回栈中Activity的情况)

activity的四种启动模式区别_launchmode图文详解 查看文章

Activity生命周期全解析、四种启动模式、IntentFilter匹配规则;查看文章

应用中的每一个Activity都是进行不同的事物处理。以邮件客户端为例,InboxActivity目的就是为了展示收件箱,这个Activity不建议创建成多个实例。而ComposeMailActivity则是用来撰写邮件,可以实例化多个此Activity对象。合理地设计Activity对象是否使用已有的实例还是多次创建,会使得交互设计更加良好,也能避免很多问题。至于想要达到前面的目标,就需要使用今天的Activity启动模式。

Android对Activity的管理:Android采用Task来管理多个Activity,当我们启动一个应用是,Android就会为其创建一个Task,然后启动这个应用的入口Activity (即 < intent-filter…/>)中配置的MAIN和LAUNCHER)。

可以把Task理解为任务栈,Task以栈的形式管理Activity:先入后出。通过调用Activity的getTaskId()的方法来获取他所在Task的ID。

launchMode在多个Activity跳转的过程中扮演着重要的角色,它可以决定是否生成新的Activity实例,是否重用已存在的Activity实例,是否和其他Activity实例共用一个Task。

a.standard:标准模式、默认模式   [ˈstændərd] 

  •  含义:每次启动一个Activity就会创建一个新的实例。
  •  注意:使用ApplicationContext去启动standard模式Activity就会报错。因为standard模式的Activity会默认进入启动它所属的任务栈,但是由于非Activity的Context没有所谓的任务栈。

b.singleTop:栈顶复用模式

  •  含义:如果新Activity已经位于任务栈的栈顶,就不会重新创建,并回调onNewIntent(intent)方法。
  • 应用场景一:可以解决重复打开activity的问题,例如 点击注册按钮(500毫秒你点击了两次) , 如果你用系统默认的启动模式, 就会打开2个注册页面,singTop启动模式的意思是开启actiivty的时候系统会先判断此activity是否存在栈顶, 如果存在就激活此实例 因此就可以解决上述的问题。
  • 应用场景二:在浏览器的书签 特点:检查栈顶是否存在这个实例 如果存在则不重新创建

c.singleTask:栈内复用模式

  •  含义:只要该Activity在一个任务栈中存在,都不会重新创建,并回调onNewIntent(intent)方法。如果不存在,系统会先寻找是否存在需要的栈,如果不存在该栈,就创建一个任务栈,并把该Activity放进去;如果存在,就会创建到已经存在的栈中。
  • 应用场景:浏览器主页面   特点:该实例在任务栈只能存在一个,如果再启动,则把上面的Activity实例全部清除。A --> B --> C -->D在D点击返回键,就返回到A。

d.singleInstance:单实例模式

  •  含义: 具有此模式的Activity只能单独位于一个任务栈中,且此任务栈中只有唯一一个实例。
  • 应用场景:来电显示界面 特点:该实例Activity会创建一个单独的任务栈,且与用户正在交互的界面的任务栈在    前端,直到全部Activity退出.


Q10:onNewIntent()调用时机? 

singleInstance:
第一次进入:onCreate onStart
在栈顶再次进入: onNewIntent
不在栈顶再次进入:onNewIntent onRestart onStart
按home键再次进入:onRestart onStart
按返回键:onRestart onStart

standard:
第一次进入:onCreate onStart
在栈顶再次进入: onCreate onStart
不在栈顶再次进入:onCreate onStart
按home键再次进入:onRestart onStart
按返回键:onRestart onStart

singleTop:
第一次进入:onCreate onStart
在栈顶再次进入:onNewIntent
不在栈顶再次进入:onCreate onStart
按home键再次进入:onRestart onStart
按返回键:onRestart onStart

singleTask:
第一次进入:onCreate onStart
在栈顶再次进入:onNewIntent
不在栈顶再次进入:onNewIntent onRestart onStart
按home键再次进入:onRestart onStart
按返回键:onRestart onStart

Activity的四种启动模式:  
    1. standard  
        默认启动模式,每次激活Activity时都会创建Activity,并放入任务栈中,永远不会调用onNewIntent()。  
    2. singleTop  
        如果在任务的栈顶正好存在该Activity的实例, 就重用该实例,并调用其onNewIntent(),否者就会创建新的实例并放入栈顶(即使栈中已经存在该Activity实例,只要不在栈顶,都会创建实例,而不会调用onNewIntent(),此时就跟standard模式一样)。  
    3. singleTask  
        如果在栈中已经有该Activity的实例,就重用该实例(会调用实例的onNewIntent())。重用时,会让该实例回到栈顶,因此在它上面的实例将会被移除栈。如果栈中不存在该实例,将会创建新的实例放入栈中(此时不会调用onNewIntent())。   
    4. singleInstance  
        在一个新栈中创建该Activity实例,并让多个应用共享该栈中的该Activity实例。一旦改模式的Activity的实例存在于某个栈中,任何应用再激活改Activity时都会重用该栈中的实例,其效果相当于多个应用程序共享一个应用,不管谁激活该Activity都会进入同一个应用中。  
当调用到onNewIntent(intent)的时候,需要在onNewIntent() 中使用setIntent(intent)赋值给Activity的Intent.否则,后续的getIntent()都是得到老的Intent。

Q11:了解哪些Activity启动模式的标记位? 

常用标记位

(1). Intent.FLAG_ACTIVITY_NEW_TASK,是为Activity指定“singleTask”启动模式

(2). Intent.FLAG_ACTIVITY_SINGLE_TOP,是为Activity指定“singleTop”启动模式

(3). FLAG_ACTIVITY_CLEAR_TOP,如果跟singleTask启动模式一起出现,如果被启动的Activity已经存在实例,则onNewIntent方法会被回调,如果被启动的Activity采用standard模式启动,那么连同它跟它之上的Activity都要出栈,并且创建新的实例放入栈顶。

(4). FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS,新的Activity不会在最近启动的Activity的列表中保存。等同于指定属性android:excludeFromRecents="true"

1.AndroidManifest中为Activity指定启动模式

   android:launchMode="singleTask"

2.通过在Intent中设置标记位来指定Activity的启动模式

   intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

3.两种方式的区别

优先级上第二种的优先级要高于第一种,第一种方式无法直接为Activity设置FLAG_ACTIVITY_CLEAR_TOP标识,第二种方式无法为Activity指定singleInstance模式。

Q12:如何启动其他应用的Activity?  

方式一:用action启动

在同一个应用中,大家都熟悉用Intent在Activity之间跳转。那么Intent能否再两个应用之间跳转呢。答案是肯定的。

在Android2.0 后的做如下:

app1 org.freedom.app1.HelloActivity

app2 org.freedom.app2.TestActivity

如何在app2的TestActivity调用app1的HelloActivity呢?

首先在app1的 AndroidManifest.xml中 HelloActivity声明中加入如下内容:



然后就可以调用了

TestActivity 中调用代码如下:

Intent Intent = new Intent();

intent.setClassName("org.freedom.app1", "org.freedom.app1.HelloActivity");

startActivity(intent);

方式二:用intent设置className或component的办法启动

查看此文

Q13:Activity的启动过程?

查看文章一

查看文章二

查看文章三

 

你可能感兴趣的:(Andorid:面试)