【我的安卓第一课】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代表点击返回键

相关推荐
下位子9 分钟前
『OpenGL学习滤镜相机』- Day6: EGL 与 GLSurfaceView 深入理解
android·opengl
java干货19 分钟前
MySQL “灵异事件”:我 INSERT id=11,为什么被 UPDATE id=10 锁住了?
android·数据库·mysql
正经教主1 小时前
【App开发】ADB 详细使用教程- Android 开发新人指南
android·adb
gx23481 小时前
MySQL-5-触发器和储存过程
android·mysql·adb
六件套是我9 小时前
redission实现延时队列
android·java·servlet
00后程序员张14 小时前
iOS 上架费用全解析 开发者账号、App 审核、工具使用与开心上架(Appuploader)免 Mac 成本优化指南
android·macos·ios·小程序·uni-app·cocoa·iphone
来来走走14 小时前
Android开发(Kotlin) 扩展函数和运算符重载
android·开发语言·kotlin
wuwu_q14 小时前
用通俗易懂 + Android 开发实战的方式,详细讲解 Kotlin Flow 中的 retryWhen 操作符
android·开发语言·kotlin
天选之女wow15 小时前
【代码随想录算法训练营——Day60】图论——94.城市间货物运输I、95.城市间货物运输II、96.城市间货物运输III
android·算法·图论
沐怡旸15 小时前
【底层机制】Android对Linux线程调度的移动设备优化深度解析
android·面试