【我的安卓第一课】Activity 生命周期下的重要函数 finish/onBackPressed

引言

Activity 生命周期是 Android 开发中的核心概念。一个 Activity 从创建到销毁会经历一系列状态,系统会在特定时刻调用相应的生命周期回调方法(如 onCreate(), onStart(), onResume(), onPause(), onStop(), onDestroy())。

深入理解并合理利用这些生命周期函数,能够帮助开发者在正确的时间执行初始化、资源管理、数据保存和释放等操作,从而开发出性能更优、用户体验更佳、稳定性更高的 Android 应用。掌握 Activity 生命周期,是迈向合格 Android 开发者的第一步。

除了生命周期方法,Android 还有一个与其息息相关的重要函数 finish()

finish()

在 Android Activity 的使用中,Activity栈 非常重要,它记录着用户访问页面的历史。每当通过 Intent 启动一个新的 Activity,它就会被压入栈顶,成为当前可见的界面,这个过程中会触发onCreate, onStart, onResume。而当用户按下返回键,栈顶 Activity 可以逐个弹出,回到之前的页面,这个过程可能触发onPause, onStoponDestroy

但有时,我们可能希望通过编程的方式,主动弹出栈顶 Activity,摆脱物理操控的限制。这时就有了一个重要的方法finish()

finish()Activity 类中的一个方法,它的作用是请求系统结束当前的 Activity 。调用 finish() 并不会立即销毁 Activity。它更像是在发送请求结束信号 。系统收到这个信号后,会将对应 Activity 出栈,并开始执行 Activity 的销毁流程,依次调用,onPause(), onStop()onDestroy()

应用场景

  1. 主动返回 这是最常见的用法。当你在一个页面(如设置页)完成操作后,希望关闭它并返回到上一个页面。

    java 复制代码
    // 在"保存"按钮的点击事件中
    saveButton.setOnClickListener(v -> {
        saveSettings(); // 保存设置
        finish(); // 关闭当前设置页,返回上一页面 // onBackPressed
    });
  2. 启动新页面前并关闭当前页面 有时我们不希望用户通过返回键回到当前页面(例如登录成功后,开屏页)。

    java 复制代码
    // 登录成功后
    loginButton.setOnClickListener(v -> {
        if (loginSuccess) {
            Intent intent = new Intent(LoginActivity.this, MainActivity.class);
            startActivity(intent);
            finish(); // 关闭登录页,这样用户无法通过返回键回到登录页
        }
    });

相似方法 onBackPressed

实际上,相比于finish(),Android 还提供了另一个方法实现 Activity 的编码关闭 onBackPressed

onBackPressed 行为如同字义,它会完美地模拟用户按下物理返回键的所有效果 。该方法最终依然是调用finish() 来实现效果。不过除了关闭当前Activity,还会有副作用

  1. 如果存在 Fragment,则优先处理 Fragment 返回栈,(本质上该方法就是点击安卓返回键)
  2. 重写点击原生返回按键时的效果
  3. 触发 onKeyDownonKeyUp (仅限点击原生返回键)

简单例子

启动新页面后删除旧页面

不使用finish 使用finish
java 复制代码
button.setOnClickListener(v -> {
    startActivity(new Intent(this,MainActivity2.class));
    finish();  // 使用finish实现进入下一activity同时,移除当前activity
});

点击两次才执行返回

finish()也可实现类似效果,但不作用于物理返回键,同时为了语义化,通常用onBackPressed()

java 复制代码
@Override
public void onBackPressed() {
    // 如果是第一次按下返回键
    if (!mIsBackPressedOnce) {
        mIsBackPressedOnce = true;
        Toast.makeText(this, "再按一次返回键退出", Toast.LENGTH_SHORT).show();

        // 2秒后重置状态
        mHandler.postDelayed(() -> mIsBackPressedOnce = false, 2000);
    } else {
        // 第二次按下返回键,执行默认的返回操作
        super.onBackPressed();
    }
}

或者

java 复制代码
getOnBackPressedDispatcher().addCallback(new OnBackPressedCallback(true) {
    @Override
    public void handleOnBackPressed() {
        if (!mIsBackPressedOnce) {
            mIsBackPressedOnce = true;
            Toast.makeText(MainActivity.this, "再按一次返回键退出", Toast.LENGTH_SHORT).show();

            // 2秒后重置状态
            mHandler.postDelayed(() -> mIsBackPressedOnce = false, 2000);
        } else {
            // 第二次按下返回键,执行默认的返回操作
            getOnBackPressedDispatcher().onBackPressed();
        }
    }
});

跳过Fragment栈直接关闭

使用finish 使用onBackPress

小结

一般情况下,finish()onBackPressed() 的作用并没有非常明显的区别,以下是两者的对比。

finish() onBackPressed()
核心语义 "程序逻辑要求结束" "模拟用户返回操作"
行为 直接、强制结束 遵循标准的返回流程
Fragment 返回栈 无视,直接关闭 Activity 先处理 Fragment 栈
调用后触发的行为 仅执行 Activity 销毁相关逻辑 除了调用 finish(),还会触发按键事件回调
推荐使用场景 业务流程完成后的关闭(前进式关闭) 响应用户"后退"意图(后退式关闭)

除了Fragment 返回栈问题与按键事件回调 问题。一般遵循语义化原则 。也即finish代表acitivty结束,onBackPressed代表点击返回键

相关推荐
Lesile2 小时前
Android:Hilt框架入门 · 在ViewUI和ComposeUI下的应用
android·android jetpack
用户423816229072 小时前
Android 16 WebView 页面顶部挖孔/通知栏不能显示UI问题排查
android
weixin_727535623 小时前
Loop 已死,Graph 新生:AI 工作流的范式革命
android·人工智能·rxjava
严同学正在努力4 小时前
从备份到恢复:我用 30 分钟恢复了误删的核心业务表
android·java·数据库·ai
梦想三三4 小时前
LangChain Output Parser 实战:从字符串到结构化数据的完整指南
android·服务器·langchain·github·uv
爱笑鱼6 小时前
Binder(八):远端进程死了,BinderProxy 为什么还能收到通知?
android
Android-Flutter7 小时前
Kotlin 冷流与热流详解
android·kotlin
zhangphil7 小时前
Android ContentProvider/ContentResolver读图片,跨进程 IPC慢
android
yueqc17 小时前
Android .so 文件压缩
android·so·包体积
龚礼鹏8 小时前
深入解析 Android Automotive (AAOS) 启动流程与 CarService 核心机制(基于 Android 16 最新源码视角)
android