Android 开发的四大组件:

  • Activity:提供UI界面显示功能;

  • Service:提供后台运行服务,不提供界面显示;

  • Broadcast Receive:用于接收广播

  • Content Provider:用于多个应用中存储和读取数据,相当于系统存储的数据库;

生命周期

生命周期函数有:

  • onCreate :当 Activity 启动时调用,常用于大部分的初始化操作,比如设置UI界面 setContentView(int)、使用 findViewById 和UI的组件进行动态交互等,

  • onStart :在 onCreateonRestart 后调用,表示 Activity 可以启动了,但是还不可见;

  • onResume :在 onStart 后调用,表示 Activity 可见

  • onPause:表示 Activity 暂停,但仍然可见

  • onStop :表示 Activity 停止,同时不可见

  • onRestart :当 Activity 重新启动时调用

  • onDestory :当 Acitivity 被销毁时调用

启动Activity: onCreate -> onStart -> onResume -> Activity 进入运行状态;

Activity进入后台(当前Activity进入任务栈、返回手机主屏幕、锁屏):onPause -> onStop -> Activity 进入停止状态;

Activity 返回前台:onRestart -> onStart -> onResume -> Activity重新进入运行状态;

Activity进入后台(系统因内存不足杀死该Activity):onPause -> onStop -> 进入后台状态,被系统杀死 -> onCreate -> onStart -> onResume;

两个Activity的跳转

从 Activity A 跳转到 Activity B:

A.onPause -> B.onCreate -> B.onStart -> B.onResume -> A.onStop

Activity A并没有被销毁,而是进入了任务栈中;

从 Activity B 按返回键回退到 ActivityA:

B.onPause -> A.onRestart -> A.onStart -> A.onResume -> B.onStop -> B.onDestroy

横竖屏的切换

在横竖屏切换的过程中,会发生 Acitivivty 被销毁并重建的过程;

此时会调用两个特殊的生命周期回调方法:

  • onSaveInstanceState:当 Activity 被销毁时调用该方法,用于存储当前界面的状态信息,方便重建后恢复界面状态;

  • onRestoreInstanceState:当 Activity 重建时将会调用该方法,用于恢复界面状态;

当 Activity 因异常情况而被终止时:

  1. onPause -> onStop -> onSaveInstanceState

  2. 系统将会调用 onSaveInstanceState 保存当前 Activity 的状态;

  3. 最后 onDestroy 回调表示当前 Activity 被销毁

  4. Activity 开始重建:onCreate -> onStart -> onRestoreInstanceState

  5. 系统将调用 onRestoreInstanceState ,并将 onSaveInstanceState 保存的 Bundle 对象传递;

  6. 最后 onResume 回调表示当前 Activity 正在运行;

onCreateonRestoreInstanceState 的参数是一样的,但是有区别:

  • onCreatesavedInstanceState 是可空的,当为空时表示第一次启动;

  • onRestoreInstanceState 是非可空的,但是拿到的 savedInstanceStateonCreate 拿到的是一样的

可以在 AndroidManifest.xml 文件对应 Activity 位置中指定如下属性:

android:configChanges = "orientation| screenSize"

以避免横竖屏切换;

Activity销毁和重建

Activity 的销毁和重建回调了 onConfigurationChanged 方法:

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

Activity启动模式

Activity 提供了四种 Activity 的启动模式;

  • 标准模式: standard

  • 栈顶复用模式: singleTop

  • 栈内复用模式:singleTask

  • 单例模式:singleInstance

通过 adb shell dumpsys activity activities 可以查看应用中任务栈的情况

标准模式 standard(默认)

每次启动 Activity,都会创建一个新的 Activity 实例并置于栈顶,同时该 Activity 运行在启动的 Activity 所在的任务栈中;

每次创建的Activity 都会重新走一遍生命周期

image-uxsx.png

栈顶复用模式 singleTop

如果指定的 Activity 已经存在于任务栈的栈顶,那么就不会创建新的实例,而是复用栈顶的 Activity;

复用时 Activity 的 onNewIntent 将会被调用;

image-hefg.png

如果指定的 Activity 并没有位于栈顶,还是会创建一个新的实例;

image-ajmd.png

栈内复用模式 singTask

如果指定的 Activity 已经存在于任务栈中,则直接将该 Activity 实例置于任务栈的栈顶,并将原本位于该 Activity 上面的所有 Activity 都从任务栈中移除;

复用时 Activity 的 onNewIntent 将会被调用;

image-rljw.png

单例模式 singleInstance

指定的 Activity 在整个 Android 系统内存中仅存在一个实例;(并非是单个任务栈)

该单例 Activity 单独存在于一个任务栈,也就是说当 Activity 启动时,系统为其单独创建一个新的任务栈;

当其他 Activity 启动该 Activity 时,将直接共享对应的任务栈;

指定启动方式

AndroidManifest.xml

静态指定:

<activity android:name=".ActivityC" 

          android:launchMode="singleTask" />

singleTask 模式结合 android:taskAffinity属性可以指定该 Activity 加载到的任务栈

  • taskAffinity:每个 Activity 都有该属性,指定该 Activity 想要进入的任务栈;

  • 如果没有指定 taskAffinity,则该值等于 Application 指定的 taskAffinity;

  • 如果Application 也没有指定,则该值等于包名;

Intent设置标志位

startActivity(
    Intent(this@MainActivity, TestActivity::class.java).apply {
        addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
    }
)

标志位:

  • Intent.FLAG_ACTIVITY_NEW_TASK 表示使用一个新的 Task 来启动 Activity,相当于 singleTask 模式;

  • FLAG_ACTIVITY_CLEAR_TOP:同一个任务栈中所有位于启动Activity上面的 Activity 都会被清空;

    • 当结合 singleTask 模式使用时,将会清空栈中位于已有 Activity 上方的所有 Activity;

    • 当结合 standard 模式使用时,将会将当前 Activity 以及上方的所有 Activity 清空,然后创建目标 Acitivity 的新实例入栈;

  • Intent.FLAG_ACTIVITY_SINGLE_TOP :表示使用 singleTop 模式启动 Activity;

  • Intent.FLAG_ACTIVITY_NO_HISTORY:表示启动方 Activity 不会进入任务栈中;

  • Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS :表示启动的 Activity 不会添加到最近应用列表,也就是无法从最近应用中看到这个启动的 Activity;

    • 与属性android:excludeFromRecents="true"效果相同。

应用场景

singleTop 可以用于消息通知跳转;

singleTask 可以用在主要界面,当启动应用时,主页位于任务栈的栈底,无论启动了多少 Activity,只需要回到主页,那么这些启动的 Activity 都能被销毁;

singleInstance 一般用于系统内部的应用,比如打电话、短信等;