Activity面试题精选

文章目录


提起四大组件之首Activity,想必是无人不知无人不晓,不论多么初级的android工程师都会比较了解,接下来就总结下关于Activity的面试题。

1.生命周期

返回栈

Q:谈一下返回栈

首先理解android是使用Task来管理活动,一个Task就是一组存放在栈里的活动的集合,这个栈就叫做返回栈,每启动一个新的活动,就会将其放入栈顶,当我们点击back回退或调用activity的finish函数处于栈顶的活动就会出栈,前一个入栈的活动就会到栈顶,系统总是显示处于栈顶的活动。

活动生命周期

Q:说下Activity的生命周期?

在这里插入图片描述

  1. onCreate()方法:活动第一次创建的时候被调用,常做初始化的操作,比如加载布局(setContentView),绑定事件(findViewById)。表示Activity正在创建
  2. onStart()方法:活动由不可见到可见的时候被调用,表示Activity正在启动,此时Activity可见但不在前台
  3. onResume()方法:活动准备好和用户进行交互时调用。表示Acitivity获得焦点,此时Activity可见且在前台
  4. onPause()方法:系统准备去启动或恢复另一个活动时调用。表示Activity正在停止,此时可做存储数据,停止动画等操作。
  5. onStop()方法:在活动完全不可见的时候调用。表示Activity即将停止
  6. onDestory()方法:在活动被销毁之前调用,表示Activity即将销毁,常做回收工作、资源释放
  7. onRestart()方法:在活动由停止状态变为运行状态之前调用。表示Activity即将重启

Q:说下活动的生存期/(onStart方法/onStop()方法与onResume()方法/onPause()方法有什么区别)

活动的生存期分为三个:1.完整生存期 2.可见生存期 3.前台生存期
完整生存期:onCreate()方法与onDestory()都处于完整生存期,一般情况下,Activity会在onCreate()方法中完成各种初始化操作,而在onDestory()方法中完成释放内存的操作。
可见生存期:onStart()方法与onStop()方法就是可见生存期Activity对于用户是可见的,但无法与用户交互。onStart()方法中对资源进行加载,onStop()方法中对资源进行释放。
前台生存期:onResume方法与onPause方法就是前台生存期,在前台生存期内,活动处于运行状态,此时可以与用户交互。

Q:说下Activity处于onPasue()下可以执行那些操作?

1.用户返回该Activity,调用onResume()方法,重新running
2.用户打开了其他Activity,就会调用onStop()方法
3.系统内存不足,拥有更高权限的应用需要内存,该Activity就会被系统回收
4.如果用户返回到onStop()的Activity又显示在前台了,系统会调用

onRestart() -> onStart() -> onResume() 然后重新running

当Activity结束(调用finish()方法)就会调用onDestory()方法释放所有占用的资源。

Q:当一个Activity打开另一个Activity都会回调哪些方法,如果ActivityB是完全透明的呢,如果启动的是一个对话框Activity呢?

A:onPause->B:onCreate->B:onStart->B:onResume->A:onStop
如果ActivityB是完全透明的或对话框Activity则不会调用onStop。

Q:当一个Activity按Home键切换到桌面后又回到该Activity回调哪些方法。

onPause->onStop->onRestart->onStart->onResume

Q:当一个Activity按back键回退时回调哪些方法

onPause->onStop->onDestory

Activity的优先级

1.可见且可以交互(前台Acitivity):正在和用户交互,优先级最高。
2.可见但不可以交互(可见但非前台Activity):比如当前Activity启动了一个对话框Activity,当前Activity就是可见但不可以交互。
3.后台Activity:已经被暂停的Activity,比如执行了onStop,优先级最低。
当系统内存不足,会按照优先级顺序从低到高去杀死目标Activity所在的进程。

Q:(1)优先级低的Activity在内存不足被回收后怎样做可以恢复到销毁前状态?/(2)横竖屏切换后怎样做可以恢复到销毁前状态?

回答:优先级低的Activity在内存不足被回收后重新打开(横竖屏切换的过程中)会引发Activity重建。
在Activity由于异常情况被终止时,系统会调用onSaveInstanceState方法来保存当前Activity的状态,该方法调用于onStop之前,与onPause方法没有时序关系。当异常终止的Activity被重建时,会调用onRestoreInstanceState方法(该方法在onStart之后),并且把Activity销毁时onSaveInstanceState保存的Bundle对象参数同时传递给onCreate方法onRestoreInstanceState方法。该方法的调用是在onStart之前。因此可通过onRestoreInstanceState(Bundle savedInstanceState)和onCreate((Bundle savedInstanceState)来判断Activity是否被重建,并取出数据进行恢复。但需要注意的是,在onCreate取出数据时一定要先判断savedInstanceState是否为空。
补充:其中onCreate和onRestoreInstanceState方法来恢复Activity的状态的区别
onRestoreInstanceState方法回调则说明bundle对象非空,不需要加非空判断,而onCreate需要非空判断。

Q:谈谈onSaveInstanceState() 与 onRestoreIntanceState()

onSaveInstanceState()

这两个方法并不是生命周期方法,它们并不一定会被触发。当应用遇到意外情况(如:内存不足、用户直接按Home键)由系统销毁一个Activity时,onSaveInstanceState() 会被调用,该方法的调用在onStop之前,与onPause没有时序关系但是当用户主动去销毁一个Activity时,例如在应用中按返回键,onSaveInstanceState()就不会被调用。因为在这种情况下,用户的行为决定了不需要保存Activity的状态。
onSaveInstanceState()时机:
(1)用户按下Home键
(2)横竖屏切换
(3)按下电源按钮(关闭屏幕显示)
(4)内存不足导致优先级的Activity被杀死

onRestoreIntanceState()

当被系统异常销毁的Activity被重建时,会调用onRestoreIntanceState或onCreate方法来恢复,而onRestoreInstance与Oncreate方法中传入的Bundle对象是销毁时onSaveInstanceState保存的,onRestoreIntanceState在onStart之后。

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

onSaveInstanceState()只适合用于保存一些临时性的状态,而onPause()适合用于数据的持久化保存。

Q:谈谈横竖屏切换过程中调用的函数

要切记这里活动已经被销毁了。
onPause->onSaveInstanceState->onStop->onDestory()->onCreate->onStart->onRestoreIntanceState->onResume

Q:如何防止横竖屏切换(配置改变)时Activity销毁并切换

通过对AndroidManifest文件的Activity中指定(configChanges)属性:

android:configChanges = “orientation| screensize”

来避免横竖屏切换时,Activity的销毁和重建,而是回调了onCofigurationChanged()方法

@Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
    }

这里附上android configChanges的所有属性解释

“mcc“ 移动国家号码,由三位数字组成,每个国家都有自己独立的MCC,可以识别手机用户所属国家。
“mnc“ 移动网号,在一个国家或者地区中,用于区分手机用户的服务商。
“locale“ 所在地区发生变化。
“touchscreen“ 触摸屏已经改变。(这不应该常发生。)
“keyboard“ 键盘模式发生变化,例如:用户接入外部键盘输入。
“keyboardHidden“ 用户打开手机硬件键盘
“navigation“ 导航型发生了变化。(这不应该常发生。)
“orientation“ 设备旋转,横向显示和竖向显示模式切换。
“fontScale“ 全局字体大小缩放发生改变

2.Activity启动模式

1.android提供了四种Activity启动模式:
标准模式(standard)
栈顶复用模式(singleTop)
栈内复用模式(singleTask)
单例模式(singleInstance)
2. activity的管理是采用任务栈的形式,上文中已经提过。
在这里插入图片描述

1.Standard模式(标准模式)

标准模式就是我们最常用的模式,在该模式下,每当启动一个新的活动,它就会在返回栈中入栈,并处于栈顶的位置。该模式不会考虑活动是否已经存在栈中,每次启动都会创建该活动的一个新的实例

下面来看第一行代码中的例子。
在这里插入图片描述
运行程序,然后在FirstActivity中连续点击两次按钮,观察logcat中打印信息。
在这里插入图片描述
可以看到,每点击一次按钮就会创建一次FirstActivity的实例,此时返回栈中也会存在3个FirstActivity的实例,因此你需要连按3次Back键才能退出程序。

2.singleTop(栈顶复用模式)

如果需要新创建的Activity处于栈顶的话,那么Activity的实例就不会重建,而是重用栈顶的实例,并回调如下方法:

   @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
    }

流程如下,当栈顶为ActivityA,而我们又一次要启动ActivityA,任务栈就不会继续增加ActivityA的实例,直接重用栈顶的实例。
在这里插入图片描述
如果栈顶不是新建的Activity,就会创建Activity新的实例,并放入栈顶。这里有个问题就是说比如我们重新调用的Activity处于任务栈中,但不位于栈顶的话,还是会创建实例。

下面来看第一行代码中的例子
我们让FirstActivity中的button1通过点击可以跳转到SecondActivity。
在这里插入图片描述
我们让SecondActivity的button2通过点击可以跳转到FirstActivity。
在这里插入图片描述
之后运行程序,在FirstActivity界面点击按钮进入到SecondActivity,然后在SecondActivity界面点击按钮,又会重新进入到FirstActivity。
在这里插入图片描述
当前Activity为SecondActivity时,任务栈task为【SecondActivity,FirstActivity】,此时点击button,跳转到FirstActivity,栈顶并非为FirstActivity,于是又会创建FirstActivity,并压入任务栈中,任务栈task为【FirstActivity,SecondActivity,FirstActivity】。

应用场景

1.在通知栏点击收到的通知,然后需要启动一个Activity,这个Activity就可以用singleTop,否则每次点击都会新建一个Activity。
2.防止快速多次点击Activity,多次启动。

3.singleTask模式(栈内复用模式)

与栈顶复用模式相对的,就是栈内复用模式,即一个栈内只有一个Activity的实例。可以在AndroidMainfest文件的Activity中指定该Activity需要加载到哪个栈中,即singleTask的Activity可以指定想要加载的目标栈。singleTask和taskAffinity配合使用,指定开启的Activity加入到哪个栈中。

<activity android:name=".Activity1"
	android:launchMode="singleTask"
	android:taskAffinity="com.lvr.task"
	android:label="@string/app_name">
</activity>

关于taskAffinity的值: 每个Activity都有taskAffinity属性,这个属性指出了它希望进入的Task。如果一个Activity没有显式的指明该Activity的taskAffinity,那么它的这个属性就等于Application指明的taskAffinity,如果Application也没有指明,那么该taskAffinity的值就等于包名。

下面来看第一行代码的实例。
继续使用singleTop中的FirstActivity和SecondActivity,并将FirstActivity的启动模式更改为SingleTask模式。
在这里插入图片描述
之后在FirstActivity中添加onRestart()方法,并打印日志。
在这里插入图片描述
最后在SecondActivity中添加onDestory()方法,并打印日志。
在这里插入图片描述
重新运行程序,在FirstActivity界面点击按钮进入到SecondActivity,然后在SecondActivity界面点击按钮,又会重新进入到FirstActivity。
在这里插入图片描述
可以看到在SecondActivity中启动FirstActivity时,会发现栈中已经有了FirstActivity的实例,并且在SecondActivity的下面,于是会让SecondActivity出栈,而FirstActivity又重新变成栈顶的Actiivity,因此会调用FirstActivity的onRestart方法与SecondActivity的onDestory方法,此时任务栈中只有FirstActivity。下图很好的说明了这个过程。
在这里插入图片描述
其实刚才说的这种情况前提在于FirstAcitivity指定要加载的栈(taskAffinity)为默认的栈。
因此该种启动模式有三种情况:
1.以singleTask启动ActivityD,同时其所需任务栈(taskAffinity)s1。当前情况下,存在s1栈,但s1栈中没有ActivityD,直接task1中压入ActivityD。
在这里插入图片描述
2.当前情况与第一行代码中情况类似。当前情况下,s1栈中存在ActivityB,因此需要将处于ActivityB上面的Activity全部出栈。
在这里插入图片描述
3.该情况为一种特殊情况,我们打算以singleTask启动ActivityD,比较栈为s2。而当前存在的栈为s1,没有s2任务栈,因此就直接创建一个新的栈,并将Activity压入。
在这里插入图片描述
总结:以SingleTask方式启动Activity时,会与指定的栈(如果没有指定就是默认栈)进行比较,如果该栈中存在该Activity就把栈中该Activity之上的Activity全部出栈,如果该栈中不存在该Activity就直接将该Acitivity压入栈中。

应用场景

应用于首页或登录页,用户在点击后退键可直接退出应用。
多数App的主页。对于大部分应用,当我们在主界面点击回退按钮的时候都是退出应用,那么当我们第一次进入主界面之后,主界面位于栈底,以后不管我们打开了多少个Activity,只要我们再次回到主界面,都应该使用将主界面Activity上所有的Activity移除的方式来让主界面Activity处于栈顶,而不是往栈顶新加一个主界面Activity的实例,通过这种方式能够保证退出应用时所有的Activity都能被销毁。

4.singleInstance(单例模式)

一看singleInstance其实就能想到是单例,以该模式启动Activity,就会直接创建一个新的任务栈,并创建该Activity的实例放入新栈中,一旦该模式的Activity实例已经存在于某个栈中,任何应用激活该Activity时都会重用该栈中的实例。
在这里插入图片描述

应用场景

呼叫来电界面。

面试题汇总

Q: 说下Activity的四种启动模式?

1.standard模式(标准模式):普通启动模式,每次启动Activity时,就会创建一个实例。
2.singletop模式(栈顶模式):当启动Activity时,会判断任务栈的栈顶是否为该Activity,如果是该Activity则不会创建实例,去**回调onNewIntent(intent)方法,否则会创建实例
3.singletask模式(栈内模式):当启动Activity时,只要该Activity在指定的栈中,就不会创建实例,去回调
onNewIntent(intent)**方法。如果不存在,会判断是否指定的栈不存在,就创建一个栈并将Activity的实例压入,如果指定的栈存在,就直接压入该栈中。
4.singleInstance模式(单实例模式):该模式下,创建Activity实例时,直接创建一个栈,栈中只有该Activity实例。之后无论哪个应用程序启动该Activity,都只会调用栈中该实例。

Q:谈谈singleTop和singleTask的区别以及应用场景

singleTop模式的含义是(参考上面问题),singleTask模式的含义是(参考上面问题),因此二者的差别为:
singleTop模式:该模式下,任务栈中可能有多个相同Activity实例,因为它只是判断当前启动的Activity是否在栈顶。
该模式的Activity会默认进入启动它所属的任务栈,不涉及任务栈的转换。常用于防止快速连续点击而创建多个Activity实例。
singleTask模式:该模式向,任务栈中只会有一个Activity实例,因为它会判断当前启动的Activity是否在当前指定的栈中。该模式下Activity可以通过taskAffinity去指定需要的任务栈,可能涉及任务栈的转换,常用于首页或登录页。因为不论我们在进入首页后进入了多少个Activity,当我们返回首页后,还是希望退出首页直接可以退出应用。该模式下会把栈中位于要启动的Activity上面的Activity都出栈。

Q:onNewIntent()调用时机?

有两个调用时机,分别是singleTop模式下与singleTask模式下启动Activity。
singleTop模式:当启动的Activity是在任务栈的栈顶时,会回调onNewIntent方法。
singleTask模式:当启动的Activity存在于任务栈中,会回调onNewIntent方法。

Q:了解哪些Activity启动模式的标记位?
  • FLAG_ACTIVITY_SINGLE_TOP:对应singleTop启动模式
  • FLAG_ACTIVITY_NEW_TASK:对应singleTask模式

参考链接:

2019校招Android面试题解1.0(上篇)
Android BestNote
《第一行代码》

发布了55 篇原创文章 · 获赞 28 · 访问量 9245

猜你喜欢

转载自blog.csdn.net/weixin_41796401/article/details/102860545