美文网首页
Activity 技术点

Activity 技术点

作者: 028257ecd619 | 来源:发表于2018-11-30 22:30 被阅读3次

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

    • onCreate:在 Activity 初始化的时候会调用一次,可以在这个方法里面初始化布局和一些数据
    • onStart:表示 Activity 已经可见了,但是还没有显示在前台,还无法和用户交互
    • onResume:此时 Activity 已经处于前台,用户可见并可以进行交互
    • onPause:表示 Activity 正在停止,可以在这个方法里面做一些不太耗时的释放工作
    • onStop:表示 Activity 即将停止,可以做一些稍微重量级的回收操作,同样不能太耗时
    • onDestory:表示 Activity 即将被销毁,可以做资源的最终释放
    • onRestart:表示 Activity 正在重新启动,当 Activity 从不可见重新变为可见时,onRestart 就会被调用

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

    • A -> B:A onPause -> B onCreate -> onStart -> onResume -> A onStop
    • B -> A:B onPause -> A onRestart -> onStart -> onResume -> B onStop -> onDestory
    • Home:onPause -> onStop
    • Home -> A:A onRestart -> onStart -> onResume

    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 属性配对使用。

    • 与 singleTask 启动模式时搭配时,待启动的 Activity 会运行在名字和 TaskAffinity 相同的任务栈中
    • 与 allowTaskReparenting 属性搭配时,当一个应用 A 启动应用 B 的某个 Activity 后,如果这个 Activity 的 allowTaskReparenting 属性为 true,那么当应用 B 被启动后,此 Activity 会直接从应用 A 的任务栈转移到应用 B的任务栈中

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

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

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

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

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

    • FLAG_ACTIVITY_NEW_TASK:为 Activity 指定 singleTask 启动模式
    • FLAG_ACTIVITY_SINGLE_TOP:为 Activity 指定 singleTop 启动模式
    • FLAG_ACTIVITY_CLEAR_TOP:启动具有此标志位的 Activity,在同一个任务栈中所有位于它之上的 Activity 都要出栈,这个标志位一般和 FLAG_ACTIVITY_NEW_TASK 搭配使用
    • FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS:具有这个标志位的 Activity 不会出现在历史 Activity 列表中,等同于在清单文件中指定 Activity 的属性 android:excludeFromRecents="true"

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

    • Intent
    • BrocardReceiver
    • ContentProvider
    • 静态变量
    • 外部存储,如 File,SharedPrefrences,数据库等
    • EventBus、RxBus

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

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

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

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

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

    • IntentFilter 的过滤信息有 action、category、data 三种
    • 只有一个 Intent 同时匹配 action、category、data 三种类别信息才算完全匹配,只有完全匹配才能启动目标 Activity
    • 一个 Activity 可以有多个 intent-filter,一个 Intetn 只要能匹配任何一组 intent-filter 就能启动目标 Activity
    • action 的匹配规则要求 Intent 中的 action 存在且必须和过滤规则中的其中一个 action 相同,这里的相同指的是字符串值完全一样,另外,action 区分大小写
    • category 的匹配规则要求 Intent 中如果含有 category,那么所有的 category 必须和过滤规则中的其中一个 category 相同
      • Intent 可以不设置 category,系统在调用 startActivity 或 startActivityForResult 的时候会默认为 Intent 加上 android.intent.categoty.DEFAULT 这个 category
      • 为了我们的 Activity 能够接收隐式调用,就必须在 intent-filter 中指定 android.intent.categoty.DEFAULT 这个 category
    • data 的匹配规则要求如果过滤规则中定义了 data,那么 Intent 中必须含有可匹配的 data,这里的匹配指的是过滤规则中出现的 data 部分也出现在了 Intent 的 data 中

    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
    

    相关文章

      网友评论

          本文标题:Activity 技术点

          本文链接:https://www.haomeiwen.com/subject/aebkcqtx.html