Activity 技术点

2018-11-30  本文已影响3人  028257ecd619

1. Activity 的生命周期有哪些?

2. 两个 Activity 跳转以及按 Home 键返回桌面的生命周期调用?

3. 横竖屏切换时的生命周期调用?

没有设置 Activity 的 android:configChanges

切屏会默认销毁当前 Activity,然后重新创建 Activity,会重走各个生命周期调用。

设置了 Activity 的 android:configChanges="orientation|screenSize"

切屏不会销毁和重新创建 Activity,只会执行 onConfigurationChanged 方法。

4. 如何保存 Activity 的状态?

在 onSaveInstanceState 方法中将数据保存在 Bundle 中,在 onCreate 方法或者 onRestoreInstanceState 方法中的 Bundle 参数取回数据。

5. 有哪些启动模式?onNewIntent 的调用时机?应用场景有哪些?

standard

标准模式,也是系统的默认模式,每启动一个 Activity 都会创建一个新的实例压入栈顶,谁启动了这个 Activity,这个 Activity 就会运行在启动它的 Activity 所在的栈中。

这个模式下的 Activity 不会调用 onNewIntent 方法

singleTop

栈顶复用模式,在这种模式下,如果新的 Activity 已经位于任务栈的栈顶,就不会创建新的实例,同时 onNewIntent 方法会被调用。

如果新 Activity 的实例存在于任务栈内,但是不在栈顶,那么就会创建新的 Activity 实例并压入栈顶。

应用场景:搜索界面、通知栏进入的界面

singleTask

栈内复用模式,在这种模式下,在这种模式下,只要一个栈中存在此 Activity 的实例,那么多次启动此 Activity 都不会创建新的实例,只会调用其 onNewIntent 方法,同时,由于 singleTask 模式默认具有 clearTop效果,会导致栈内所有在此 Activity 之上的 Activity 全部出栈。

应用场景:应用主页

singleInstance

单实例模式,这个模式具有 singleTask 所有的特性,还加强了一点,这个模式的 Activity 只能单独的位于一个任务栈中。

6. 在 Service 或者 Receiver 中,如何启动 Activity,原理是什么?

因为 standard 模式下的 Activity 会默认运行在启动它的 Activity 的任务栈中,但是非 Activity 的 Context 并没有所谓的任务栈,所以直接启动就会报错,需要为待启动的 Activity 指定 FLAG_ACTIVITY_NEW_TASK 标志位,这样启动它的时候就会为它创建一个新的任务栈,相当于以 singleTask 模式启动了这个 Activity。

7. TaskAffinity 属性的作用是什么?

TaskAffinity 属性标识了一个 Activity 所需要的任务栈的名字。

默认情况下,所有 Activity 所需的任务栈的名字都为包名。

TaskAffinity 属性主要和 singleTask 启动模式或者 allowTaskReparenting 属性配对使用。

8. 有几种方式给 Activity 指定启动模式,哪种方式优先级高?

有两种方式,第一种是在清单文件中指定,第二种是通过在 Intent 中设置标志位来指定。

第二种方式的优先级高于第一种。

第一种方式无法直接为 Activity 设定 FLAG_ACTIVITY_CLEAR_TOP 标识,第二种方式无法为 Activity 指定 singleInstance 模式 。

9. 启动 Activity 有哪些常用的 Flag?

10. 两个 Activity 之间传递数据的方法?

11. 启动 Activity 的方式有哪些,优先级如何?

第一种显式调用,需要明确地指定被启动 Activity 的包名、类名等。

第二种隐式调用,需要 Intent 能匹配目标 Activity 的 IntentFilter 中设置的过滤规则,如果不匹配则无法启动目标 Activity。

显式调用的优先级高于隐式调用。

12. IntentFilter 的匹配规则有哪些?

13. setResult 和 finish 的调用关系

问题:如果不能在 setResult() 之后立刻调用 finish() 方法,那么 setResult() 该在哪里调用?

Activity-A 通过 startActvityForResult() 打开了 Activity-B,B 退回 A 过程

B-onPause
A-onActivityResult
A-onRestart
A-onStart
A-onResume
B-onStop
B-onDestory

由源码可以看出,Activity 返回 result 是在 finish 的时候,也就是调用 setResult() 方法必须在 finish 之前,

又因为 A 的 onActivityResult() 需要在 B 的 onPause() 之后且 A 的 onRestart() 之前调用,而 onPause() 的调用不一定是在 finish() 之前,所以 B 中的 setResult() 方法要放在 B 的 onPause 之前调用。

解决方法:可以重写 onBackPressed() 方法,在执行默认的返回方法之前 setResult()

@Override
public void onBackPressed(){
    setResult();
    super.onBackPressed();
}

执行过程为

B-onBackPressed
B-finish
B-onPause
A-onActivityResult
A-onRestart
A-onStart
A-onResume
B-onStop
B-onDestroy
上一篇下一篇

猜你喜欢

热点阅读