42. 【Android教程】活动:Activity

简介: 42. 【Android教程】活动:Activity

从今天开始将会学习一个非常重要的概念——Android 四大组件,在 Android 中几乎所有的功能都和四大组件密不可分,而 Activity 是其中出场率最高的组件,也是对用户感知度最高的组件,当然也可以说是四大组件中最重要的一个组件。我们前面的绝大部分逻辑代码也都是在 Activity 中实现的,接下来详细介绍一下第一大组件——Activity。

1. Activity 的基本定义

An activity is a single, focused thing that the user can do. Almost all activities interact with the user, so the Activity class takes care of creating a window for you in which you can place your UI with setContentView. While activities are often presented to the user as full-screen windows, they can also be used in other ways: as floating windows (via a theme with android.R.attr.windowIsFloating set) or embedded inside of another activity (using ActivityGroup).


以上是摘自官方文档中对 Activity 的部分解释,用我不太流利的英语给大家翻译一下, 英语不太好的同学可以将就着看看:


Activity 提供给用户一个单一的、独立操作的用户界面,几乎所有的 Activity 都可以和用户进行交互,所以 Activity 类的主要功能是创建一个窗口来承载我们通过setContentView设置的 UI 界面,从而展示给用户。大部分场景下,Activity 会以全屏的形式占满手机屏幕,但是也支持浮窗或者内嵌的形式。


其实简而言之,Activity 就是一个用户界面,类似 Windows 系统里的窗口的概念,而第一个启动的 Activity,我们称之为主 Activity。

2. Activity 的生命周期

如果你学习过 C/C++ 或者 Java 开发应该很熟悉main()函数,没错,一切代码都是从main()函数开始的。在 Android 中也有类似的概念,每个 Android 应用程序都有一个主 Activity(启动 Activity),而其中的onCreate()方法就是所有代码的起点。

2.1 生命周期的各个流程

Android 系统为每个 Activity 设计了完备的生命周期,在各个不同的生命周期我们都可以做不同的工作,Activity 生命周期流程图如下:

上图中的每一个矩形框代表一个生命周期方法,Activity 一共有 7 个生命周期。当然我们在实际开发中并不需要全部都实现,只需根据具体需求在合适的时机去实现相应的生命周期方法即可,这就要求开发者对每个生命周期回调的时机和意义比较了解,下面我们来解读一下每个生命周期的调用时机:


onCreate():

在 Activity 被创建的时候回调,也是 Activity 的第一个生命周期方法,在整个生命周期中只会执行一次。通常会在这里执行页面的初始化逻辑,大部分的 Activity 相关的代码都会在这里执行

onStart():

当 Activity 对用户可见的时候回调,注意此时可能还不能交互,可以用来统计页面曝光

onResume():

当 Activity 获取系统焦点的时候回调,此时已经可以和用户交互

onPause():

当 Activity 暂停的时候回调,此时用户已经不能交互,并且暂停执行正常业务代码。通常这时候会回调下一个或者上一个 Activity 的onResume()

onStop():

当 Activity 不可见的时候回调,此时结束曝光

onRestart():

在“Stop”之后,再次回到 Activity 时触发此方法

onDestroy():

此生命周期触发标志着 Activity 销毁,是最后一个生命周期,和onCreate()一样,只会调用一次,接着系统就会回收掉这部分资源

这 7 个生命周期不是单纯的线性运动,从上图可以看出除了第一个和最后一个:onCreate()、onDestroy()之外,其他的都是可以反复循环的。

2.2 生命周期常见问题及误区

**另外要特别注意的,也是面试中非常容易被问到的一个经典问题:**从 Activity A 启动到 Activity B,再从 B 退回到 A,所经历的生命周期方法依次是哪几个?

大家可以先根据生命周期流转图及各生命周期的定义自行思考一下,分割线后给出答案。


我们来分析一下这个问题,首先是 Activity A 的启动:


A onCreate -> A onStart() -> A onResume()


到这里 A 就启动完毕了,接下来启动 Activity B,此时系统会将焦点移动到 B 上,故 A 的 onPause() 会被调用,接着创建 Activity B,那么流程是这样的:


A onPause() -> B onCreate() -> B onStart() -> B onResume()


此时 B 已经启动完毕,大家注意到 A 的onStop()自始至终还未执行,我们再次回忆一下onStop()的定义:“当 Activity 不可见的时候回调”。所以此时要分两种情况,如果 Activity B 是全屏的类型,那么在 B 启动之后系统会回调 Activity A 的 onStop();但是前面提到过,Activity可以是浮窗类型,此时 A 的onStop()则不会被回调,这是一个关键点,大家一定要记住!!


所以从 Activity A 跳转 Activity B 的生命周期触发顺序如下:


A onCreate -> A onStart() -> A onResume() -> 跳转 B -> A onPause() -> B onCreate() -> B onStart() -> B onResume() -> if (B is full screen) { A onStop() }


此时如果从 B 在返回到 A 的话,按照以上原理不难理解:


B onPause() -> A onRestart() -> A onStart() -> A onResume() -> B onStop() -> B onDestroy()


由于从 B 返回 A 需要销毁 B,所以此时不论 A 是否是全屏类型都会在 A 恢复之后依次调用 B 的onStop()和onDestroy()。这个是面试必考题,大家务必掌握!

3. Activity 示例

关于 Activity 的使用其实从本教程的最开始就一直在用,我们通常都是将核心逻辑放在了onCreate()之中,比如setContentView设置布局样式,findViewById()获取布局中的控件实例,绑定监听器等等,所以 Activity 的用法相信大家并不陌生,这里主要是希望大家对除了 onCreate()方法之外的其他生命周期时机有所了解。我们将在 7 个生命周期中加入 Log 日志,观察一下各个生命周期的回调时机,编写 Activity 代码如下:

package com.emercy.myapplication;
 
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
 
public class MainActivity extends Activity {
    String TAG = "Android Lifecycle";
 
    // 第一个被调用的方法,当 Activity 被创建时调用
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d(TAG, "The onCreate() event");
    }
 
    // Activity 可见
    @Override
    protected void onStart() {
        super.onStart();
        Log.d(TAG, "The onStart() event");
    }
 
    // Activity 获取焦点,可交互
    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "The onResume() event");
    }
 
    // Activity 失焦
    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "The onPause() event");
    }
 
    // Activity 停止,不可见
    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG, "The onStop() event");
    }
 
    // Activity 销毁
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "The onDestroy() event");
    }
 
    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d(TAG, "The onRestart() event");
    }
}

编译运行,系统自动启动 MainActivity,此时观察 Logcat 输出:

接着点击“Home”退出 Activity,然后切换回来,观察 Logcat 如下:

最后点击 back 退出 App,再次观察 Logcat:

通过 Logcat 可以观察到生命周期的跳转符合预期。

4. 小结

本节介绍了 Android 四大组件中的第一大组件,也是用的最多、责任最大的组件,其中最关键的是要掌握各个生命周期的调用时机及含义。

首先分析了 Activity 7 个生命周期的流转,以及各个生命周期的意义,接着通过一个示例配合具体的用户行为通过 Logcat 的形式打印了生命周期的变化,理论结合实际相信你会对 Activity 的生命周期有了更深的理解。中间还分享了一个关键点,也是面试中经常遇到的问题,希望大家牢牢掌握!


相关文章
|
7天前
|
网络协议 Android开发 数据安全/隐私保护
Android手机上使用Socks5全局代理-教程+软件
Android手机上使用Socks5全局代理-教程+软件
23 2
|
17天前
|
缓存 网络协议 安全
49. 【Android教程】HTTP 使用详解
49. 【Android教程】HTTP 使用详解
16 1
|
17天前
|
XML 存储 JSON
51. 【Android教程】JSON 数据解析
51. 【Android教程】JSON 数据解析
27 2
|
17天前
|
存储 API 文件存储
47. 【Android教程】SharedPreferences 存储
47. 【Android教程】SharedPreferences 存储
21 2
|
6天前
|
Android开发
Android面试题之activity启动流程
该文探讨了Android应用启动和Activity管理服务(AMS)的工作原理。从Launcher启动应用开始,涉及Binder机制、AMS回调、进程创建、Application和Activity的生命周期。文中详细阐述了AMS处理流程,包括创建ClassLoader、加载APK、启动Activity的步骤,以及权限校验和启动模式判断。此外,还补充了activity启动流程中AMS的部分细节。欲了解更多内容,可关注公众号“AntDream”。
10 1
|
13天前
|
存储 Java Android开发
Android上在两个Activity之间传递Bitmap对象
Android上在两个Activity之间传递Bitmap对象
13 2
|
17天前
|
存储 安全 大数据
46. 【Android教程】文件存储
46. 【Android教程】文件存储
17 3
|
17天前
|
存储 编解码 Android开发
58. 【Android教程】音频录制:MediaRecord
58. 【Android教程】音频录制:MediaRecord
14 2
|
17天前
|
Web App开发 移动开发 前端开发
52. 【Android教程】网页视图:WebView
52. 【Android教程】网页视图:WebView
14 1
|
17天前
|
XML 存储 JavaScript
50. 【Android教程】xml 数据解析
50. 【Android教程】xml 数据解析
16 1