安卓Activity的生命周期

1.1 Activity的生命周期分析

1.1.1 典型情况下的生命周期分析

正常情况下,Activity有如下生命周期。

  1. onCreate:表示Activity正在被创建,这是生命周期的第一个方法,通常用来做一些初始化工作,比如调用setContentView,加载数据等。
  2. onRestart:表示Activity正在被重新启动,一般情况下是由于Activity从不可见重新变为可见时,onRestart会被调用。
  3. onStart:表示Activity正在被启动,即将开始,此时Activity已经可见,但是还没有出现在前台,无法与用户交互。这个时候可以理解为Activity已经显示出来了,但是我们看不到。
  4. onResume:表示Activity已经可见,并且出现在前台开始活动。
  5. onPause:表示Activity正在停止,正常情况下,紧接着onStop会被调用。此时可以做一些存储数据、停止执行动画等工作,但不能太耗时,因为会影响到新的Activity的显示,因为转场时onPause必须执行完,新的Activity的onResume才会执行
  6. onStop:表示Activity即将停止(Activity被完全遮挡),可以做一些轻量级的回收工作,同样不能太耗时
  7. onDestroy:表示Activity即将被销毁,可以做一些资源回收工作。
  • Activity官方生命周期示例图
    在这里插入图片描述

  • 具体情况下Activity生命周期切换过程
    1)第一次启动:onCreate -> onStart -> onResume
    2)当用户打开新的Activity或者切回到桌面时,onPause -> onStop,这里有一种特殊情况,如果该Activity是透明主题,不会回调onStop
    3)当用户再次切回原Activity时,onRestart -> onStart -> onResume
    4)当用户按下back键时,onPause -> onStop -> onDestroy
    5)当Activity被系统回收后再次打开,生命周期方法回调过程同1,但只是生命周期方法一样,此外还多出现场保存方法,属于异常情况下Activity的生命周期处理

  • Activity1启动Activity2,两个Activity生命周期函数回调顺序
    Activity1:onPause
    Activity2:onCreate
    Activity2:onStart
    Activity2:onResume
    Activity1:onStop

  • Q:onStart和onResume,onPause和onStop从描述上看来差不多,对我们来说有什么实质的不同?
    A:onStart和onStop是从Activity是否可见这个角度来回调的,而onResume和onPause是从Activity是否位于前台来回调的,主要区分Activity可见和可交互的不同,使用中可以只保留一个。

1.1.2 异常情况下的生命周期分析

  1. 资源相关的系统配置发生改变导致的Activity被杀死并重新创建
    例如,屏幕旋转时,activity的生命周期:
    MainActivity@5c08997:onPause -> onStop -> onDestroy
    MainActivity@cace036:onCreate -> onStart -> onResume
      可见,原Activity被杀死,并创建了新的Activity,并且由于Activity是在异常情况下被终止,系统会调用onSaveInstanceState保存当前Activity的状态。当Activity被重新创建后,系统调用onRestoreInstanceState,并且把异常销毁时onSaveInstanceState保存的Bundle对象作为参数传递给onCreate和onRestoreInstanceState,onRestoreInstanceState的调用时机在onStart之后
      在onSaveInstanceState和onRestoreInstanceState中,系统自动为我们做了一些恢复工作。在Activity异常情况下需要重新创建时,系统默认为我们保存当前Activity的视图状态,并且在Activity重启后为我们恢复这些数据,比如文本框中用户输入的数据,ListView的滚动位置等,具体想知道哪些View具有自动恢复数据的能力,查看对应类的onSaveInstanceState和onRestoreInstanceState这两个方法即可,例如TextView.onSaveInstanceState
  • 使用onSaveInstanceState和onRestoreInstanceState保存数据
    
    class MainActivity : AppCompatActivity() {
    	override fun onCreate(savedInstanceState: Bundle?) {
        	super.onCreate(savedInstanceState)
      		setContentView(R.layout.activity_main)
        	var data = ""
        	if (savedInstanceState != null) {
            	data = savedInstanceState.getString("extra_data")?:""
        	}
        	Log.d("west", "$this onCreate $data")
    	}	
    	
    	override fun onSaveInstanceState(outState: Bundle) {	
        	super.onSaveInstanceState(outState)
        	outState.putString("extra_data", "test")
        	Log.d("west", "$this onSaveInstanceState")
    	}
    
    	override fun onRestoreInstanceState(savedInstanceState: Bundle) {
           	super.onRestoreInstanceState(savedInstanceState)
    	    val data = savedInstanceState.getString("extra_data")
       		Log.d("west", "$this onRestoreInstanceState $data")
    	}
    }
    
    当屏幕旋转时,生命周期函数回调顺序:
    myapplication.MainActivity@5b74796 onPause
    myapplication.MainActivity@5b74796 onStop
    myapplication.MainActivity@5b74796 onSaveInstanceState
    myapplication.MainActivity@5b74796 onDestroy
    myapplication.MainActivity@b3b2960 onCreate test
    myapplication.MainActivity@b3b2960 onStart
    myapplication.MainActivity@b3b2960 onRestoreInstanceState test
    myapplication.MainActivity@b3b2960 onResume
    Activity异常销毁时,调用onSaveInstanceState保存了data,重建后onCreate和onRestoreInstanceState都打印出了test,onRestoreInstanceState的调用时机在onStart之后
    基于Android5.0系统的《Android艺术探索》中提到onSaveInstanceState在onStop之前调用,但我实际操作(Android 10/MUI 12)发现onSaveInstanceState在onStop之后调用的,具体原因还需要继续研究
  1. 资源内存不足导致低优先级的Activity被杀死
    其数据存储和恢复过程和1完全一致。
    分析Activity的优先级情况,优先级从高到低分别为:

    1. 前台Activity —— 正在和用户交互的Activity,优先级最高
    2. 可见但非前台的Activity —— 被dialog挡住或被透明Activity挡住
    3. 后台Activity —— 已经被暂停的Activity,比如执行了onStop

    当系统内存不足时,会按优先级从低到高去杀死目标Activity所在的进程,并执行onSaveInstanceState和onRestoreInstanceState。

  2. 系统配置发生改变时,如何不重新创建Activity
    比如屏幕旋转时,不希望activity重建,在activity便签下加上:android:configChanges=“orientation|screenSize”

    <activity android:name=".MainActivity"
        android:configChanges="orientation|screenSize">
        <intent-filter>
    	    <action android:name="android.intent.action.MAIN" />
    	    <category android:name="android.intent.category.LAUNCHER" />	
    	</intent-filter>
    </activity>
    

    《android艺术探索》中提到在activity便签下加上android:configChanges=“orientation”,没有"screenSize",在android4.0以上不生效。

    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            Log.d("west", "onCreate")
        }
    
        override fun onConfigurationChanged(newConfig: Configuration) {
            super.onConfigurationChanged(newConfig)
            Log.d("west", "onConfigurationChanged")
        }
    }
    

    没加上android:configChanges,旋转屏幕后:
    D/west: onCreate
    D/west: onCreate
    D/west: onCreate
    加上android:configChanges后,旋转屏幕时:
    D/west: onCreate
    D/west: onConfigurationChanged
    D/west: onConfigurationChanged,
    可见,加上android:configChanges,旋转屏幕时,不会触发activity重建,只会触发配置改变回调

参考书目《android开发艺术探索》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值