【Android面试储备】Activity知识点全家桶;看完这篇你还不会,请给我寄刀片
这篇文章将解决你以下几个疑问:
-
Activity的生命周期在不同场景有何种不同提现?
-
Activity启动模式有哪些?有何不同?
-
Activity是如何处理数据的?
-
Activity和Context有什么关系?
-
Android中有哪些进程?
一、生命周期

1.1 Dialog 弹出时
- 如果是单纯是创建的
dialog,Activity并不会执行生命周期的方法 - 但是如果是跳转到一个不是全屏的
Activity的话, 当然就是按照正常的生命周期来执行了 - 即
onPasue()->onPause()( 不会执行原Activity的onStop(), 否则上个页面就不显示了 )
1.2 横竖屏切换时
- 不设置
Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次(Android3.2之前) - 设置
Activity的android:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次 - 设置
Activity的android:configChanges="orientation|keyboardHidden"时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法 - 注意:还有一点,非常重要,一个
Android的变更细节!当API >12时,需要加入screenSize属性,否则屏幕切换时即使你设置了orientation系统也会重建Activity!
1.3 不同场景下 Activity 生命周期的变化过程
-
启动
Activity:onCreate()--->onStart()--->onResume(),Activity进入运行状态。 -
锁屏时会执行
onPause()和onStop(), 而开屏时则应该执行onStart()onResume(), 而开屏时则应该执行onStart()onResume() -
Activity退居后台: 当前Activity转到新的Activity界面或按Home键回到主屏:onPause()--->onStop(),进入停滞状态。 -
Activity返回前台:onRestart()--->onStart()--->onResume(),再次回到运行状态。 -
Activity退居后台: 且系统内存不足, 系统会杀死这个后台状态的Activity,若再次回到这个Activity,则会走onCreate()-->onStart()--->onResume()
1.4 将一个 Activity 设置成窗口的样式
只需要给我们的 Activity 配置如下属性即可。 android:theme="@android:style/Theme.Dialog"
1.5 修改 Activity 进入和退出动画
- 可以通过两种方式 , 一是通过定义
Activity的主题 ,二是通过覆写Activity的overridePendingTransition方法。 - 通过设置主题样式在
styles.xml中编辑代码 , 添加themes.xml文件:在AndroidManifest.xml中给指定的Activity指定theme。 - 覆写
overridePendingTransition方法:overridePendingTransition(R.anim.fade, R.anim.hold);
1.6 Activity 的四种状态
-
runnig:用户可以点击,activity处于栈顶状态。 -
paused:activity失去焦点的时候,被一个非全屏的activity占据或者被一个透明的activity覆盖,这个状态的activity并没有销毁,它所有的状态信息和成员变量仍然存在,只是不能够被点击。(内存紧张的情况,这个activity有可能被回收) -
stopped:这个activity被另外一个activity完全覆盖,但是这个activity的所有状态信息和成员变量仍然存在(除了内存紧张) -
killed:这个activity已经被销毁,其所有的状态信息和成员变量已经不存在了。
1.7 如何处理异常退出
-
Activity异常退出的时候 -->onPause()-->onSaveInstanceState()-->onStop()-->onDestory() -
需要注意的是
onSaveInstanceState()方法与onPause并没有严格的先后关系,有可能在onPause之前,也有可能在其后面调用,但会在onStop()方法之前调用 -
异常退出后又重新启动该
Activity-->onCreate()-->onStart()-->onRestoreInstanceState()-->onResume() -
搞懂这个生命周期的执行后就可以回答了,首先要知道面试官的意思:是要重新启动并恢复这个
Activity还是说直接退出整个app -
如果要恢复则要在
onSaveInstanceState()中进行保存数据并在onRestoreInstanceState()中进行恢复 -
如果是要退出
app的话就要捕获全局的异常信息,并退出app -
当然个人建议是使用
UncaughtExceotionHandler来捕获全局异常进行退出app的操作,这样会减少之前崩溃所造成的后遗症!
1.8 什么是 onNewIntent
- 如果
IntentActivity处于任务栈的顶端,也就是说之前打开过的Activity,现在处于onPause、onStop状态的话,其他应用再发送Intent的话 - 执行顺序为:
onNewIntent,onRestart,onStart,onResume。
二、启动模式
2.1 启动模式
-
Activity一共有四种launchMode:standard、singleTop、singleTask、singleInstance。 -
Standard模式(默认模式)
- 说明: 每次启动一个
Activity都会又一次创建一个新的实例入栈,无论这个实例是否存在。 - 生命周期:每次被创建的实例
Activity的生命周期符合典型情况,它的onCreate、onStart、onResume都会被调用。 - 举例:此时
Activity栈中以此有A、B、C、D四个Activity,此时D处于栈顶,启动模式为Standard模式。若在D Activity中加入点击事件,须要跳转到类型为B Activity。结果是还有一个B Activity进入栈中,成为栈顶。

SingleTop模式(栈顶复用模式)
- 说明:分两种处理情况:须要创建的
Activity已经处于栈顶时,此时会直接复用栈顶的Activity。不会再创建新的Activity;若须要创建的Activity不处于栈顶,此时会又一次创建一个新的Activity入栈,同Standard模式一样。 - 生命周期:若情况一中栈顶的
Activity被直接复用时,它的onCreate、onStart不会被系统调用,由于它并没有发生改变。可是一个新的方法onNewIntent会被回调(Activity被正常创建时不会回调此方法)。

- 举例:此时
Activity栈中以此有A、B、C、D四个Activity,此时D处于栈顶,启动模式为SingleTop模式。情况一:在D Activity中加入点击事件,须要跳转到还有一个同类型的D Activity。结果是直接复用栈顶的D Activity。

情况二:在 C Activity 中加入点击事件,须要跳转到 D Activity。结果是创建一个新的 Activity 入栈。成为栈顶。
SingleTask模式(栈内复用模式)
- 说明:若须要创建的
Activity已经处于栈中时,此时不会创建新的Activity,而是将存在栈中的Activity上面的其他Activity所有销毁,使它成为栈顶。 - 如果是在别的应用程序中启动它,则会新建一个
task,并在该task中启动这个Activity,singleTask允许别的Activity与其在一个task中共存,也就是说,如果我在这个singleTask的实例中再打开新的Activity,这个新的Activity还是会在singleTask的实例的task中。 - 生命周期:同
SingleTop模式中的情况一同样。仅仅会又一次回调Activity中的onNewIntent方法

- 举例:此时
Activity栈中以此有A、B二个Activity。此时B处于栈顶,启动模式为SingleTask模式。在B Activity中加入点击事件,须要跳转到C Activity。结果是创建新的C Activity放入栈顶 。

情况二:在 C Activity 中加入点击事件,须要跳转到还有一个 C Activity 。结果是将 C Activity 上面的D 销毁,使 C Activity 成为栈顶。
SingleInstance模式(单实例模式)
- 说明:
SingleInstance比较特殊,是全局单例模式,是一种加强的SingleTask模式。它除了具有它所有特性外,还加强了一点:只有一个实例,并且这个实例独立运行在一个task中,这个task只有这个实例,不允许有别的Activity存在。 - 这个经常使用于系统中的应用,比如
Launch、锁屏键的应用等等,整个系统中仅仅有一个!所以在我们的应用中一般不会用到。了解就可以。 - 举例:比方
A Activity是该模式,启动A后。系统会为它创建一个单独的任务栈,由于栈内复用的特性。兴许的请求均不会创建新的Activity,除非这个独特的任务栈被系统销毁。

2.2 启动模式的使用方式
- 在
Manifest.xml中指定Activity启动模式
- 一种静态的指定方法
- 在
Manifest.xml文件里声明Activity的同一时候指定它的启动模式 - 这样在代码中跳转时会依照指定的模式来创建
Activity。
- 启动
Activity时。在Intent中指定启动模式去创建Activity
- 一种动态的启动模式
- 在
new一个Intent后 - 通过
Intent的addFlags方法去动态指定一个启动模式。
- 注意:以上两种方式都能够为
Activity指定启动模式,可是二者还是有差别的。
- 优先级:动态指定方式即另外一种比第一种优先级要高,若两者同一时候存在,以另外一种方式为准。
- 限定范围:第一种方式无法为
Activity直接指定FLAG_ACTIVITY_CLEAR_TOP标识,另外一种方式无法为Activity指定singleInstance模式。
2.3 启动模式的实际应用场景
这四种模式中的
Standard模式是最普通的一种,没有什么特别注意。而SingleInstance模式是整个系统的单例模式,在我们的应用中一般不会应用到。所以,这里就具体解说SingleTop和SingleTask模式的运用场景:
SingleTask模式的运用场景
- 最常见的应用场景就是保持我们应用开启后仅仅有一个
Activity的实例。 - 最典型的样例就是应用中展示的主页(
Home页)。 - 假设用户在主页跳转到其他页面,运行多次操作后想返回到主页,假设不使用
SingleTask模式,在点击返回的过程中会多次看到主页,这明显就是设计不合理了。
SingleTop模式的运用场景
- 假设你在当前的
Activity中又要启动同类型的Activity - 此时建议将此类型
Activity的启动模式指定为SingleTop,能够降低Activity的创建,节省内存!
- 注意:复用
Activity时的生命周期回调
- 这里还须要考虑一个
Activity跳转时携带页面參数的问题。 - 由于当一个
Activity设置了SingleTop或者SingleTask模式后,跳转此Activity出现复用原有Activity的情况时,此Activity的onCreate方法将不会再次运行。onCreate方法仅仅会在第一次创建Activity时被运行。 - 而一般
onCreate方法中会进行该页面的数据初始化、UI初始化,假设页面的展示数据无关页面跳转传递的參数,则不必操心此问题 - 若页面展示的数据就是通过
getInten()方法来获取,那么问题就会出现:getInten()获取的一直都是老数据,根本无法接收跳转时传送的新数据!
- 以下,通过一个样例来具体解释:

- 以上代码中的
CourseDetailActivity在配置文件里设置了启动模式是SingleTop模式,依据上面启动模式的介绍可得知,当CourseDetailActivity处于栈顶时。 - 再次跳转页面到
CourseDetailActivity时会直接复用原有的Activity,并且此页面须要展示的数据是从getIntent()方法得来,可是initData()方法不会再次被调用,此时页面就无法显示新的数据。 - 当然这样的情况系统早就为我们想过了,这时我们须要另外一个回调
onNewIntent(Intent intent)方法。此方法会传入最新的intent,这样我们就能够解决上述问题。这里建议的方法是又一次去setIntent。然后又一次去初始化数据和UI。代码例如以下所看到的:

- 这样,在一个页面中能够反复跳转并显示不同的内容。
2.4 快速启动一个 Activity
- 这个问题其实也是比较简单的,就是不要在
Activity的onCreate方法中执行过多繁重的操作,并且在onPasue方法中同样不能做过多的耗时操作。
2.5 Activity 的 Flags
- 标记位既能够设定Activity的启动模式,如同上面介绍的,在动态指定启动模式,比方
FLAG_ACTIVITY_NEW_TASK和FLAG_ACTIVITY_SINGLE_TOP等。它还能够影响Activity的运行状态 ,比方FLAG_ACTIVITY_CLEAN_TOP和FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS等。 - 以下介绍几个基本的标记位,切勿死记,理解几个就可以,须要时再查官方文档。

FLAG_ACTIVITY_NEW_TASK
- 作用是为
Activity指定“SingleTask”启动模式。跟在AndroidMainfest.xml指定效果同样
FLAG_ACTIVITY_SINGLE_TOP
- 作用是为
Activity指定“SingleTop”启动模式,跟在AndroidMainfest.xml指定效果同样。
FLAG_ACTIVITY_CLEAN_TOP
- 具有此标记位的
Activity,启动时会将与该Activity在同一任务栈的其他Activity出栈。 - 一般与
SingleTask启动模式一起出现。 - 它会完毕
SingleTask的作用。 - 但事实上
SingleTask启动模式默认具有此标记位的作用
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
- 具有此标记位的
Activity不会出如今历史Activity的列表中 - 使用场景:当某些情况下我们不希望用户通过历史列表回到
Activity时,此标记位便体现了它的效果。 - 它等同于在
xml中指定Activity的属性.
2.6 onNewInstent()方法什么时候执行
这个是启动模式中的了,当此 Activity 的实例已经存在,并且此时的启动模式为 SingleTask 和 SingleInstance ,另外当这个实例位于栈顶且启动模式为 SingleTop 时也会触发 onNewInstent() 。
三、数据
3.1 Activity 间通过 Intent 传递数据大小限制
Intent在传递数据时是有大小限制的,这里官方并未详细说明,不过通过实验的方法可以测出数据应该被限制在1MB之内(1024KB)- 我们采用传递
Bitmap的方法,发现当图片大小超过1024(准确地说是1020左右)的时候,程序就会出现闪退、停止运行等异常(不同的手机反应不同) - 因此可以判断
Intent的传输容量在1MB之内。
3.2 内存不足时系统会杀掉后台的Activity,若需要进行一些临时状态的保存,在哪个方法进行

Activity的onSaveInstanceState()和onRestoreInstanceState()并不是生命周期方法,它们不同于onCreate()、onPause()等生命周期方法,它们并不一定会被触发。onSaveInstanceState()方法,当应用遇到意外情况(如:内存不足、用户直接按Home键)由系统销毁一个Activity,onSaveInstanceState()会被调用。- 但是当用户主动去销毁一个
Activity时,例如在应用中按返回键,onSaveInstanceState()就不会被调用。 - 除非该
activity不是被用户主动销毁的,通常onSaveInstanceState()只适合用于保存一些临时性的状态,而onPause()适合用于数据的持久化保存。
3.3 onSaveInstanceState() 被执行的场景
- 系统不知道你按下
HOME后要运行多少其他的程序,自然也不知道activity A是否会被销毁 - 因此系统都会调用
onSaveInstanceState(),让用户有机会保存某些非永久性的数据。以下几种情况的分析都遵循该原则:
- 当用户按下
HOME键时 - 长按
HOME键,选择运行其他的程序时 - 锁屏时
- 从
activity A中启动一个新的activity时 - 屏幕方向切换时
3.4 两个 Activity 之间跳转时必然会执行的方法
一般情况下比如说有两个 activity , 分别叫 A , B ,当在 A 里面激活 B 组件的时候, A 会调用 onPause() 方法,然后 B 调用 onCreate() , onStart() , onResume() 。
这个时候 B 覆盖了窗体, A 会调用 onStop() 方法. 如果 B 是个透明的,或者 是对话框的样式, 就不会调用 A 的 onStop() 方法。
3.5 用 Intent 去启动一个Activity 之外的方法
- 使用
adb shell am命令
am启动一个activityadb shell am start com.example.fuchenxuan/.MainActivityam发送一个广播,使用actionadb shell am broadcast -a magcomm.action.TOUCH_LETTER
四、Context
4.1 Context , Activity , Appliction 的区别
- 相同:
Activity和Application都是Context的子类。 Context从字面上理解就是上下文的意思, 在实际应用中它也确实是起到了管理 上下文环境中各个参数和变量的总用, 方便我们可以简单的访问到各种资源。- 不同:维护的生命周期不同。
Context维护的是当前的Activity的生命周期,Application维护的是整个项目的生命周期。 - 使用
context的时候, 小心内存泄露, 防止内存泄露
4.2 Context 是什么
- 它描述的是一个应用程序环境的信息,即上下文。
- 该类是一个抽象(
abstract class)类,Android提供了该抽象类的具体实 现类(ContextIml)。 - 通过它我们可以获取应用程序的资源和类, 也包括一些应用级别操作, 例如:启动一个
Activity,发送广播,接受Intent,信息,等。
五、进程
5.1 Android 进程优先级
- 前台 / 可见 / 服务 / 后台 / 空
5.1.1 前台进程:Foreground process
- 用户正在交互的
Activity(onResume()) - 当某个
Service绑定正在交互的Activity - 被主动调用为前台
Service(startForeground()) BroadcastReceiver正在执行onReceive()
5.1.2 可见进程:Visible process
- 我们的
Activity处在onPause()(没有进入onStop()) - 绑定到前台
Activity的Service
5.1.3 服务进程:Service process
- 简单的
startService()启动。
5.1.4 后台进程:Background process
- 对用户没有直接影响的进程 ---
Activity处于onStop()的时候。 android:process=":xxx"
5.1.5 空进程:Empty process
- 不含有任何的活动的组件。(
Android设计的,处于缓存的目的,为了第二次启动更快,采取的一个权衡)
5.2 可见进程
可见进程指部分程序界面能够被用户看见,却不在前台与用户交互的进程。例如,我们在一个界面上弹出一个对话框(该对话框是一个新的
Activity),那么在对话框后面的原界面是可见的,但是并没有与用户进行交互,那么原界面就是可见进程。
- 一个进程满足下面任何一个条件都被认为是可视的:
- 寄宿着一个不是前台的活动,但是它对用户仍可见(它的
onPause()方法已经被调用)。举例来说,这可能发生在,如果一个前台活动在一个对话框(其他进程的)运行之后仍然是可视的,比如输入法的弹出时。 - 寄宿着一个服务,该服务绑定到一个可视的活动。
- 一个可视进程被认为是及其重要的且不会被杀死,除非为了保持前台进程运行。
5.3 服务进程
- 服务进程是通过
startService()方法启动的进程,但不属于前台进程和可见进程。例如,在后台播放音乐或者在后台下载就是服务进程。 - 系统保持它们运行,除非没有足够内存来保证所有的前台进程和可视进程。
5.4 后台进程
- 后台进程是一个保持着一个当前对用户不可视的活动(已经调用
Activity对象的onStop()方法)(如果还有除了UI线程外其他线程在运行话,不受影响)。
例如我正在使用
Home键让
- 这些进程没有直接影响用户体验,并且可以在任何时候被杀以收回内存用于一个前台、可视、服务进程。
- 一般地有很多后台进程运行着,因此它们保持在一个
LRU(least recently used,即最近最少使用,如果您学过操作系统的话会觉得它很熟悉,跟内存的页面置换算法LRU一样)列表以确保最近使用最多的活动的进程最后被杀。
5.5 空进程
- 空进程是一个没有保持活跃的应用程序组件的进程,不包含任何活跃组件。
- 保持这个进程可用的唯一原因是作为一个
cache以提高下次启动组件的速度。系统进程杀死这些进程,以在进程cache和潜在的内核cache之间平衡整个系统资源。 android进程的回收顺序从先到后分别是:空进程,后台进程,服务进程,可见进程,前台进程。
5.6 什么是 ANR,如何避免
5.6.1 什么是ANR
ANR,全称为Application Not Responding。- 在
Android中,如果你的应用程序有一段时间没有响应,系统会向用户显示一个对话框,这个对话框称作应用程序无响应对话框。
5.6.2 用户行为
- 用户可以选择让程序继续运行,也可以让程序停止运行。
- 他们在使用你的应用程序时,并不希望每次都要处理这个对话框。
- 因此,在程序里对响应性能的设计很重要,这样,系统不会显示
ANR给用户。
5.6.3 Android不同组件ANR超时时间不同
- 不同的组件发生
ANR的时间不一样,主线程(Activity、Service)是5秒,BroadCastReceiver是10秒。
5.6.4 解决方案
- 将所有耗时操作,比如访问网络,
Socket通信,查询大量SQL语句,复杂逻辑计算等都放在子线程中去,然后通过handler.sendMessage、runonUITread、AsyncTask等方式更新UI,以确保用户界面操作的流畅度。 - 如果耗时操作需要让用户等待,那么可以在界面上显示进度条。
5.7 android的任务栈 Task

- 一个
Task包含的就是activity集合,android系统可以通过任务栈有序的管理activity - 一个app当中可能不止一个任务栈,在某些情况下,一个
activity也可以独享一个任务栈(singleInstance模式启动的activity)
Android面试
这份资料我从2020年春招开始,就会将各博客、论坛。网站上等优质的Android开发中高级面试题收集起来,然后全网寻找最优的解答方案。每一道面试题都是百分百的大厂面经真题+最优解答。包知识脉络 + 诸多细节。节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
篇幅原因,下面展示部分截图,由于篇幅原因,如有需要以下完整学习笔记PDF,可以在我的GitHub免费自取!!
正文总共分为6个部分:
Java 基础(★★)
Java 高级(★★)
Android 基础(★★★)
Android 高级(★★★)
Android 项目(★★★)
项目面试常见问题(★★★)
一、Java 基础(★★)
面向对象思想
多态
异常处理
数据类型
Java 的 IO
集合
Java 多线程

Java 高级(★★)
Java 中的反射
Java 中的动态代理
Java 中的设计模式&回收机制
Java 的类加载器

Android 基础(★★★)
Android 基本常识
Activity
Service
BroadCastReceiver
ContentProvider&数据库

Android 中的布局
ListView
JNI & NDK
Android 中的网络访问
Intent
Fragment

Android 高级(★★★)
Android 性能优化
Android 屏幕适配
AIDL
自定义控件
Android 中的事件处理
Android 签名
Android 中的动画
网络协议
其他

项目面试常见问题(★★★)
- 开发周期
- 项目中遇到的难题
- 项目中最大的收获
- 项目是如何上线的
- 项目是如何盈利的
- 绘制项目架构图
- 项目开发流程
- 你在项目中的角色
- 你负责项目中的哪些模块
- 讲讲你负责模块的具体实现
- 项目中都用到了哪些第三发框架
- 有没有自己写过框架
- 业余时间你是如何提高自己(学习)的
- 有没有自己的技术 blog
- 你的职业规划
- 为什么离职
- 为什么选择我们公司
- 说说你们项目的亮点和不足
- 你们的项目是如何保持风格一致的
- 项目架构是如何搭建的
- 屏幕适配是如何解决的
- 都看过哪些源码
- 项目版本是如何升级的
- 用的什么版本控制工具
- 你能独立开发吗
- App 跟服务器是如何交互的
- 需求文档写过吗
- 接口文档写过吗
- 云服务器都用过哪些
- 第三方平台都用过哪些
简历+社招解答+经典HR面试解析
以上是整理总结的Android中高级面试遇到的真题解析,希望对大家有帮助;同时很多人经常也会遇到很多关于简历制作,职业困惑、HR经典面试问题回答等有关面试的问题。同样我也搜集整理了全套简历制作、金三银四社招困惑、HR面试等问题解析,有疑问,可以提供专业的解答。

对于Android开发的朋友来说应该是最全面最完整的面试资料,为了更好地整理每个模块,我参考了很多网上的优质博文和项目,力求不漏掉每一个知识点。很多朋友靠着这些内容进行复习,拿到了BATJ等大厂的offer,这个资料也已经帮助了很多的安卓开发者,希望也能帮助到你。
由于篇幅原因,如有需要以上完整学习笔记PDF,可以在我的GitHub免费自取!!
文末
我一直觉得技术面试不是考试,考前背背题,发给你一张考卷,答完交卷等通知。
首先,技术面试是一个 认识自己 的过程,知道自己和外面世界的差距。
更重要的是,技术面试是一个双向了解的过程,要让对方发现你的闪光点,同时也要 试图去找到对方的闪光点,因为他以后可能就是你的同事或者领导,所以,面试官问你有什么问题的时候,不要说没有了,要去试图了解他的工作内容、了解这个团队的氛围。
找工作无非就是看三点:和什么人、做什么事、给多少钱,要给这三者在自己的心里划分一个比例。
最后,祝愿大家在这并不友好的环境下都能找到自己心仪的归宿!
感谢您阅读这篇文章,如果可以收到您的点赞,我将非常荣幸,希望我们可以成为朋友,一起分享交流Android技术。


浙公网安备 33010602011771号