Android基础 - activity生命周期

本文深入解析Android中Activity的生命周期,包括正常情况下的生命周期流程、特殊场景下的生命周期回调,以及资源变化和内存不足时Activity的处理机制。通过实例代码演示了不同生命周期方法的调用顺序,帮助开发者更好地理解和掌握Activity生命周期管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.生命周期

生命周期如下如图所示:

1.1生命周期示意图

1.1 典型生命周期分析:

在正常情况下,生命周期为如下经历:

  • onCreate():Activity正在被创建,在这个方法中可以做一些初始化工作,比如调用setContentView去加载布局资源、初始化Activity所需要的资源等。

  • onRestart():Activity正在重新启动,一般情况下,在当前activity由不可见变为可见的时候调用该方法。这种情况一般由用户行为所致。

  • onStart():activity正在被启动,即将开始,这时候activity可见但不在前台,用户无法操作。可以理解为activity已经显示了但是我们还看不到。

  • onResume() : 此时activity已经可见,并且可以交互。和onStart()方法的区别在于onStart()时activity还在后台,不能交互。

  • onPause(): activity正在停止,正常情况下onStop会被接着调用。如果在这个时候快速返回当前activity则会直接调用onResume()。但是这种情况一般很难实现。

  • onStop(): activity即将停止,可以做一些重量级的回收工作但是不能做耗时操作。

  • onDestriy(): activity即将被销毁。

具体实例如下:(使用kotlin实现)

class MainActivity : AppCompatActivity() {
    val TAG : String = "MainActivity"
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        LogUtils.d("onCreate")
    }
    override fun onPause() {
        super.onPause()
        LogUtils.d("onPause")
    }
    override fun onDestroy() {
        super.onDestroy()
        LogUtils.d("onDestroy")
    }
    override fun onStart() {
        super.onStart()
        LogUtils.d("onStart")
    }
    override fun onResume() {
        super.onResume()
        LogUtils.d("onResume")
    }

    override fun onStop() {
        super.onStop()
        LogUtils.d("onCreate")
    }
    override fun onRestart() {
        super.onRestart()
        LogUtils.d("onRestart")
    }
    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        LogUtils.d("onNewIntent")
    }
}
1.1.1 正常情况下生命周期方法回调情况如下:
  • 一般情况下启动新的activity的生命周期方法执行顺序为:

onCreate() -> onStart() -> onRessume()

  • 当用户打开新的activity或切换到桌面的时候,回调顺序为:

onPause() -> onStop()
此时存在特殊情况:当启动的activity主题为透明,则当前activity不会回调onStop()方法。

  • 当用户再次回到原Activity时。,回调如下:

onRestart() -> onStart() -> onResume()

  • 当用户按返回键回退时,回调如下:

onPause() -> onStop() -> onDestroy()

1.1.1.1 启动新的activity时的生命周期
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        LogUtils.d("onCreate")
        // 跳转到第二个页面
        btn2activity.setOnClickListener {
            var sIntent = Intent()
            sIntent.setClass(MainActivity@this,SecondActivity::class.java)
            startActivity(sIntent)
        }
    }

第二个页面:

 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)
        LogUtils.d("onCreate")
    }
    override fun onPause() {
        super.onPause()
        LogUtils.d("onPause")

    }

    override fun onDestroy() {
        super.onDestroy()
        LogUtils.d("onDestroy")

    }

    override fun onStart() {
        super.onStart()
        LogUtils.d("onStart")

    }

    override fun onResume() {
        super.onResume()
        LogUtils.d("onResume")

    }

    override fun onStop() {
        super.onStop()
        LogUtils.d("onCreate")

    }

    override fun onRestart() {
        super.onRestart()
        LogUtils.d("onRestart")

    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        LogUtils.d("onNewIntent")

    }

生命周期日志为:

2019-02-16 15:08:23.340 29929-29929/com.xyd.activitylaunchmodedemo D/LogUtils➀: ╔══════════════════════════════════════════════════════════════
2019-02-16 15:08:23.340 29929-29929/com.xyd.activitylaunchmodedemo D/LogUtils➁: ║ MainActivity.onPause(MainActivity.kt:26)
2019-02-16 15:08:23.340 29929-29929/com.xyd.activitylaunchmodedemo D/LogUtils➂: ╟──────────────────────────────────────────────────────────────
2019-02-16 15:08:23.340 29929-29929/com.xyd.activitylaunchmodedemo D/LogUtils➃: ║ onPause
2019-02-16 15:08:23.340 29929-29929/com.xyd.activitylaunchmodedemo D/LogUtils➄: ╚══════════════════════════════════════════════════════════════
2019-02-16 15:08:23.429 29929-29929/com.xyd.activitylaunchmodedemo D/LogUtils➀: ╔══════════════════════════════════════════════════════════════
2019-02-16 15:08:23.430 29929-29929/com.xyd.activitylaunchmodedemo D/LogUtils➁: ║ SecondActivity.onCreate(SecondActivity.kt:15)
2019-02-16 15:08:23.430 29929-29929/com.xyd.activitylaunchmodedemo D/LogUtils➂: ╟──────────────────────────────────────────────────────────────
2019-02-16 15:08:23.430 29929-29929/com.xyd.activitylaunchmodedemo D/LogUtils➃: ║ onCreate
2019-02-16 15:08:23.430 29929-29929/com.xyd.activitylaunchmodedemo D/LogUtils➄: ╚══════════════════════════════════════════════════════════════
2019-02-16 15:08:23.431 29929-29929/com.xyd.activitylaunchmodedemo D/LogUtils➀: ╔══════════════════════════════════════════════════════════════
2019-02-16 15:08:23.431 29929-29929/com.xyd.activitylaunchmodedemo D/LogUtils➁: ║ SecondActivity.onStart(SecondActivity.kt:31)
2019-02-16 15:08:23.431 29929-29929/com.xyd.activitylaunchmodedemo D/LogUtils➂: ╟──────────────────────────────────────────────────────────────
2019-02-16 15:08:23.432 29929-29929/com.xyd.activitylaunchmodedemo D/LogUtils➃: ║ onStart
2019-02-16 15:08:23.432 29929-29929/com.xyd.activitylaunchmodedemo D/LogUtils➄: ╚══════════════════════════════════════════════════════════════
2019-02-16 15:08:23.435 29929-29929/com.xyd.activitylaunchmodedemo D/LogUtils➀: ╔══════════════════════════════════════════════════════════════
2019-02-16 15:08:23.435 29929-29929/com.xyd.activitylaunchmodedemo D/LogUtils➁: ║ SecondActivity.onResume(SecondActivity.kt:37)
2019-02-16 15:08:23.435 29929-29929/com.xyd.activitylaunchmodedemo D/LogUtils➂: ╟──────────────────────────────────────────────────────────────
2019-02-16 15:08:23.435 29929-29929/com.xyd.activitylaunchmodedemo D/LogUtils➃: ║ onResume
2019-02-16 15:08:23.435 29929-29929/com.xyd.activitylaunchmodedemo D/LogUtils➄: ╚══════════════════════════════════════════════════════════════
2019-02-16 15:08:23.803 29929-29929/com.xyd.activitylaunchmodedemo D/LogUtils➀: ╔══════════════════════════════════════════════════════════════
2019-02-16 15:08:23.805 29929-29929/com.xyd.activitylaunchmodedemo D/LogUtils➁: ║ MainActivity.onStop(MainActivity.kt:50)
2019-02-16 15:08:23.805 29929-29929/com.xyd.activitylaunchmodedemo D/LogUtils➂: ╟──────────────────────────────────────────────────────────────
2019-02-16 15:08:23.805 29929-29929/com.xyd.activitylaunchmodedemo D/LogUtils➃: ║ onStop
2019-02-16 15:08:23.805 29929-29929/com.xyd.activitylaunchmodedemo D/LogUtils➄: ╚══════════════════════════════════════════════════════════════

1.1.2 异常情况下生命周期分析
1. 资源相关的系统配置发生改变导致Activity被杀死并重启

异常情况下Activity的重建过程

当系统配置发生变化后(例如默认情况下的横竖屏切换),activity会被销毁,onPause、onStop、onDestroy方法均会被调用,同时,activity是在异常情况下被销毁,所以还会调用activity的onSaveInstanceState方法,保存当前activity的状态。这个方法调用是在onStop之前,它和onPause没有顺序关系。这个方法的调用只是在异常情况下,正常情况下不会调用。当activity被重新创建之后,系统会调用onRestroeInstanceState方法,并且将activity销毁时onSaveInstanceState方法保存的Bundle对象最为参数同时传递给onRestroeInstanceState和onCreate方法。因此我们可以通过onRestroeInstanceState和onCreate方法来判断activity是否被重建,如果被重建,则使用bundle对象的参数恢复。

示例如下:

  override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        LogUtils.d("onCreate")
        if (savedInstanceState != null) {
            val string = savedInstanceState!!.getString("extra_test")
            LogUtils.d("[onCreate] restroe extra_test == " + string)
        }
     }
override fun onSaveInstanceState(outState: Bundle?) {
        super.onSaveInstanceState(outState)
        LogUtils.d("onSaveInstanceState")
        outState?.putString("extra_test","test")
    }

    override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
        super.onRestoreInstanceState(savedInstanceState)
        val string = savedInstanceState!!.getString("extra_test")
        LogUtils.d("[onRestoreInstanceState] restroe extra_test == " + string)
    }

横竖屏切换时的生命周期调用如下:

2019-02-16 16:33:46.975 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➀: ╔══════════════════════════════════════════════════════════════
2019-02-16 16:33:46.975 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➁: ║ MainActivity.onPause(MainActivity.kt:31)
2019-02-16 16:33:46.975 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➂: ╟──────────────────────────────────────────────────────────────
2019-02-16 16:33:46.975 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➃: ║ onPause
2019-02-16 16:33:46.975 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➄: ╚══════════════════════════════════════════════════════════════
2019-02-16 16:33:46.976 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➀: ╔══════════════════════════════════════════════════════════════
2019-02-16 16:33:46.977 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➁: ║ MainActivity.onSaveInstanceState(MainActivity.kt:73)
2019-02-16 16:33:46.977 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➂: ╟──────────────────────────────────────────────────────────────
2019-02-16 16:33:46.977 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➃: ║ onSaveInstanceState
2019-02-16 16:33:46.977 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➄: ╚══════════════════════════════════════════════════════════════
2019-02-16 16:33:46.978 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➀: ╔══════════════════════════════════════════════════════════════
2019-02-16 16:33:46.979 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➁: ║ MainActivity.onStop(MainActivity.kt:55)
2019-02-16 16:33:46.979 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➂: ╟──────────────────────────────────────────────────────────────
2019-02-16 16:33:46.979 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➃: ║ onStop
2019-02-16 16:33:46.979 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➄: ╚══════════════════════════════════════════════════════════════
2019-02-16 16:33:46.979 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➀: ╔══════════════════════════════════════════════════════════════
2019-02-16 16:33:46.980 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➁: ║ MainActivity.onDestroy(MainActivity.kt:37)
2019-02-16 16:33:46.980 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➂: ╟──────────────────────────────────────────────────────────────
2019-02-16 16:33:46.980 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➃: ║ onDestroy
2019-02-16 16:33:46.980 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➄: ╚══════════════════════════════════════════════════════════════
2019-02-16 16:33:47.055 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➀: ╔══════════════════════════════════════════════════════════════
2019-02-16 16:33:47.056 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➁: ║ MainActivity.onCreate(MainActivity.kt:17)
2019-02-16 16:33:47.056 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➂: ╟──────────────────────────────────────────────────────────────
2019-02-16 16:33:47.056 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➃: ║ onCreate
2019-02-16 16:33:47.056 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➄: ╚══════════════════════════════════════════════════════════════
2019-02-16 16:33:47.056 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➀: ╔══════════════════════════════════════════════════════════════
2019-02-16 16:33:47.056 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➁: ║ MainActivity.onCreate(MainActivity.kt:20)
2019-02-16 16:33:47.056 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➂: ╟──────────────────────────────────────────────────────────────
2019-02-16 16:33:47.056 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➃: ║ [onCreate] restroe extra_test == test
2019-02-16 16:33:47.056 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➄: ╚══════════════════════════════════════════════════════════════
2019-02-16 16:33:47.057 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➀: ╔══════════════════════════════════════════════════════════════
2019-02-16 16:33:47.058 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➁: ║ MainActivity.onStart(MainActivity.kt:43)
2019-02-16 16:33:47.058 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➂: ╟──────────────────────────────────────────────────────────────
2019-02-16 16:33:47.058 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➃: ║ onStart
2019-02-16 16:33:47.058 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➄: ╚══════════════════════════════════════════════════════════════
2019-02-16 16:33:47.058 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➀: ╔══════════════════════════════════════════════════════════════
2019-02-16 16:33:47.059 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➁: ║ MainActivity.onRestoreInstanceState(MainActivity.kt:80)
2019-02-16 16:33:47.059 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➂: ╟──────────────────────────────────────────────────────────────
2019-02-16 16:33:47.059 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➃: ║ [onRestoreInstanceState] restroe extra_test == test
2019-02-16 16:33:47.059 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➄: ╚══════════════════════════════════════════════════════════════
2019-02-16 16:33:47.059 3025-3025/com.xyd.activitylaunchmodedemo D/ActivityThread: add activity client record, r= ActivityRecord{76602aa token=android.os.BinderProxy@30b5a73 {com.xyd.activitylaunchmodedemo/com.xyd.activitylaunchmodedemo.MainActivity}} token= android.os.BinderProxy@30b5a73
2019-02-16 16:33:47.061 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➀: ╔══════════════════════════════════════════════════════════════
2019-02-16 16:33:47.061 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➁: ║ MainActivity.onResume(MainActivity.kt:49)
2019-02-16 16:33:47.061 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➂: ╟──────────────────────────────────────────────────────────────
2019-02-16 16:33:47.061 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➃: ║ onResume
2019-02-16 16:33:47.061 3025-3025/com.xyd.activitylaunchmodedemo D/LogUtils➄: ╚══════════════════════════════════════════════════════════════

从日志文件可以看出:在切换时,先调用onSaveInstanceState()方法,保存数据,然后切换之后调用onCreate和onRestoreInstanceState方法,获取保存的数据。

2. 资源内存不足导致优先级低的activity被杀死

首先先分清activity的优先级,如下三种:

  1. 前台activity —正在和用户交互,优先级最高
  2. 可见但非前台activity— 比如activity中弹出了一个dialog对话框,导致activity可见但是位于后台,无法和用户交互。
  3. 后台activity — 已经被暂停的activity,比如A启动B之后,A的优先级低,B的优先级最高

当系统内存不足时,系统会按照上边的优先级,有低到高的优先级杀死目标activity所在的进程,并在后续通过onSaveInstanceState和onRestoreInstanceState 方法来存储和恢复数据。如果一个进程中没有四大组件在执行,那么这个进程很快就会被系统杀死。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值