Android 面试2 - Activity 知识
1. Activity 生命周期函数
- 完整生命周期
onCreate() -> onStart() -> onResume() -> onPause() -> onStop() -> onDestroy() - 在 onPause() 之后重新进入 onResume()
onPause() -> onResume() - 在 onStop() 之后重新进入 onResume()
onStop() -> onRestart() -> onResume() - Activity 状态分析
系统中的所有 Activity 被一个 Activity 栈管理,一个新的 Activity 启动时被放置在栈顶,前一个 Activity 保留在栈中。在这个过程中,一个 Activity 会有四中状态变化:
- 在屏幕的前台(Activity 栈顶),叫做活跃状态或运行状态;
- 如果一个 Activity 失去焦点但依然可见,则该 Activity 处于暂停状态;
- 如果一个 Activity 完全不可兼容,则处于 Stopped 状态,此时该 Activity 依然保持所有成员状态与状态信息,但已不可见;
- 一个处于 Paused 或 Stopped 状态的 Activity,其内存会被系统回收,此时 Activity 就结束了其生命周期。
2. Activity 状态的保存
当一个 Activity 进入 stopped 状态时,如果有一个优先级别更高的 Activity 需要获得资源,系统就可能会破坏处于stop状态的Activity,回收其内存,此时这个Activity对象会被 destroyed,此时我们必须调用一个 onSaveInstanceState() 方法来保存我们的 Activity 的对象状态。
onSaveInstanceState(Bundle outState) 这个方法接受一个 Bundle 类型参数,我们可以将需要保存的状态通过 Bundle 的 putString(), putInt() 方法保存起来。
如果此时这个 Activity 对象被 destroy 了,当再次打开这个 Activity 时,又会重新创建这个 Activity,这个时候系统会将 onSaveInstanceState() 方法中的 Bundle 对象传递给 Activity 的 onCreate()和 onRestoreInstanceState() 方法。
3. Activity 的 Launch Mode
本段参考文章为:基础总结篇之二:Activity的四种launchMode,在此致谢!
launchMode 在多个 Activity 跳转的过程中扮演着重要的角色,它可以决定是否生成新的 Activity 实例,是否重用已存在的 Activity 实例,是否和其他 Activity 实例公用一个 task等。
task 是一个具有栈结构的对象,一个 task 可以管理多个 Activity,启动一个应用,也就创建一个与之对应的t ask。
一个 Activity 具有四种 Launch Mode:
- Standard
- SingleTop
- SingleTask
- SingleInstance
我们可以在 AndroidManifest.xml 中的 <activity>
中为当前 actvity 设置 android:launchMode="xxx" 属性。
1. Standard
默认模式,不管是否已经存在实例,每次都会重新创建新的实例。
2. SingleTop
如果系统发现有对应的 Activity 实例位于栈顶,则重用该实例,否则(1. 不存在对应实例,2. 存在对应实例但不位于栈顶)就创建新的实例。
3. SingleTask
如果发现有对应的 Activity 实例,则使此 Activity 实例之上的其他 Activity 实例统统出栈,使此 Activity 实例成为栈顶对象,显示到幕前。否则就创建新的实例。
4. SingleInstance
这种启动模式比较特殊,因为它会启用一个新的栈结构,将 Acitvity 放置于这个新的栈结构中,并保证不再有其他 Activity 实例进入。
singleInstance启动模式可能是最复杂的一种模式。下面以一个“分享”应用为例说明其用法。
问题:假如我们有一个share应用,其中的ShareActivity是入口Activity,也是可供其他应用调用的Activity,我们把这个Activity的启动模式设置为singleInstance,然后在其他应用中调用。
首先,我们以如下方式配置 activity :
<activity android:name=".ShareActivity" android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SINGLE_INSTANCE_SHARE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
然后我们在其他应用中这样启动该 Activity:
Intent intent = new Intent("android.intent.action.SINGLE_INSTANCE_SHARE");
startActivity(intent);
当我们打开 ShareActivity 后再按后退键回到原来界面时,ShareActivity 做为一个独立的个体存在,如果这时我们打开 share 应用,无需创建新的 ShareActivity 实例即可看到结果,因为系统会自动查找,存在则直接利用。
4. 屏幕旋转过程中 Activity 的生命周期变化
- 在
<activity>
标签中没有设置 android:configChanges="orientation|keyboardHiddenorientation|keyboard|Hidden" 标签
当前 Activity 会被销毁,然后从 onCreate() 开始重新创建当前 Activity 实例。 - 设置了 android:configChanges="orientation|keyboardHiddenorientation|keyboard|Hidden"标签
当前 Activity 不会被销毁,并会执行 onConfigurationChanged() 方法