这是我参与「第四届青训营 」笔记创作活动的的第1天.
Activity组件是安卓开发者第一个接触到的组件, 也是理解安卓应用程序的重要内容。
本文主要记录Activity组件相关的理论知识。 小蒟蒻浅显的总结, 难免有错误和表述不清, 请批评指正。
Activity的概念
Activity类是 Android 应用的关键组件,而 Activity 的启动和组合方式则是该平台应用模型的基本组成部分。在编程范式中,应用是通过main()方法启动的,而 Android 系统与此不同,它会调用与其生命周期特定阶段相对应的特定回调方法来启动Activity实例中的代码。
在我们熟悉的由编译型语言写出的程序中, 会有一个固定的入口即main函数, 程序总是从main函数进入并执行。 而在android系统的应用场景中, app不总是从固定的的位置开始运行, 如我们在qq未运行的情况下打开qq, 会进入聊天列表界面; 在qq不久前使用过时, 会还原退出qq时的界面; 又比如在抖音中选择qq登录, 会直接打开qq中的授权登录界面。
Activity类的作用就是实现形如上面这些场景的功能。
对Activity的一些理解
一个Acivity其实就是一个app界面, app里的界面切换其实就是由一个Activity换成了另一个Activity; Activity的启动可以是显式的(如按下某个按钮, 在按钮控件的代码中我们调用了一个Activity), 也可以是隐式的(由android系统捕捉动作并调用).
Activity的创建
声明Activity
要使应用能够使用 Activity,必须在清单中声明 Activity 及其特定属性。
具体的操作是找到manifests目录的AndroidManifest.xml文件, 在<application>标签中增加一个<activity>标签, 一个activity标签就代表一个activity类, 标签中必须声明的属性是name, 即类名
以下是android studio自动生成的empty界面app中的清单文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.trudbot.androidapp">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.AndroidApp"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
声明 intent 过滤器
Intent 过滤器是 Android 平台的一项非常强大的功能。借助这项功能,您不但可以根据显式请求启动 Activity,还可以根据隐式请求启动 Activity。** **例如,显式请求可能会告诉系统“在 Gmail 应用中启动‘发送电子邮件’Activity”,而隐式请求可能会告诉系统“在任何能够完成此工作的 Activity 中启动‘发送电子邮件’屏幕”。当系统界面询问用户使用哪个应用来执行任务时,这就是 intent 过滤器在起作用。
上面的xml文件中, activity标签如下
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
intent过滤器中绑定了一个动作<action android:name="android.intent.action.MAIN" />
即Main, Main动作其实就是打开app, 所以每次我们打开app时都会由系统调用这个Activity, 也就是我们打开app默认显示的界面.
实现Activity类
一个类只有继承了Activity或其子类才是一个Activity类, 在当前的安卓版本中一般继承AppCompatActivity类
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
Activity生命周期
当用户浏览、退出和返回到您的应用时,您应用中的
Activity实例会在其生命周期的不同状态间转换。Activity类会提供许多回调,这些回调会让 Activity 知晓某个状态已经更改:系统正在创建、停止或恢复某个 Activity,或者正在销毁该 Activity 所在的进程。
大白话讲就是Activity会根据app的状态的切换执行不同的代码.如刚开启这个Activity时, 或者是从app切回了桌面.
为了在 Activity 生命周期的各个阶段之间导航转换,Activity 类提供六个核心回调:
onCreate()、onStart()、onResume()、onPause()、onStop()和onDestroy()。当 Activity 进入新状态时,系统会调用其中每个回调。
这六个回调函数也就是Activity类中要选择性重写的函数, 其中onCreate函数是必须重写的, 它会在系统首次创建 Activity 时触发。Activity 会在创建后进入“已创建”状态。
回调函数更详尽的介绍参加官方文档
任务栈
任务是用户在执行某项工作时与之互动的一系列 Activity 的集合。这些 Activity 按照每个 Activity 打开的顺序排列在一个堆栈中。
如从Activity A进入了Activity B时, B就被添加到了栈顶负责与用户交互; 当我们点击回退键时, B被销毁并弹出栈中, A再次成为栈顶.
在任务栈中且非栈顶的Activity会调用onStop后处于停止状态, 系统会保留其界面的当前状态.
有关任务中的每个新 Activity 如何添加到返回堆栈的图示。当用户按返回按钮时,当前 Activity 会销毁,上一个 Activity 将恢复。
如果用户不断按回退键, 栈中元素会依次出栈, 直到栈空; 移除堆栈中的所有 Activity 后,该任务将不复存在。
Activity启动模式
试想这样一个场景: 我们在qq 的"消息"页面中点击了导航栏中的"联系人", 又在"联系人"页面中点击了"消息"重新回到了消息页面, 按上面说的任务栈模式, 栈底到栈顶会有消息->联系人->消息三个Activity实例.
"消息"这个Activity被重复创建了两次实例, 而且其实两次都是没什么区别的.这显然不合理.
为了能够优化类似的问题,Android提供四种启动模式来修改系统这一默认行为。
standard模式
默认的模式, 每次启动Activity都会创建新的实例放到栈顶.
singleTask模式
又叫栈内复用模式, 启动某个Activity时, 若栈中已经存在这个Activity的实例, 就会复用这个实例. 复用时, 会将他上面的Activity全部出栈.
singleTop模式
又叫栈顶复用模式, 应对的是"在A中启动A"这样的场景, 此时A已经处于栈顶, 在singleTop模式下会复用A, 并调用onNewIntent方法去除之前操作的痕迹.
singleInstance 模式
此模式的Activity将不能和其它Activity共享任务栈. 这里假设A的启动模式为singleInstance.
- 当第一次启动A时, 会单独为A新开一个任务栈, 而原任务栈不变
- 当A已经实例化过、拥有了自己的任务栈, 再在某处启动A时, 会直接复用A的实例, 类似于singleTop
- 当在A中启动标准模式的Activity, 会为它也新开一个任务栈
引用参考
一篇文章搞懂 Activity 启动模式 - 掘金 (juejin.cn)
Android技能树 — Activity小结 - 掘金 (juejin.cn)
了解 Activity 生命周期 | Android 开发者 | Android Developers (google.cn)