四大组件——Activity(1)

493 阅读6分钟

一.Activity的生命周期

按照惯例,先放一张Activity生命周期的图片,可以先从整体把握生命周期中各个方法的调用顺序,稍后再从代码中对各个方法调用做相关说明。

从图中我们可以看出,Activity的主要生命周期有:onCreate()OnStart()OnRestart()OnResume()OnPause()OnStop()OnDestroy() 这7个方法。

二. 项目工程说明

采用语音:Kotlin(基于1.2.61)
测试机:魅族 M15(基于Android 7.1.2)
项目名称:activity_basic_use
编译版本:
minSdkVersion 17
targetSdkVersion 26

三.生命周期方法的调用

先新建4个文件,MainActivitySecondActivityThirdActivityFourthActivity,其中MainActivity用来做跳转测试的主ActivitySecondActivity是普通的ActivityThirdActivity是以Dialog形式显示的ActivityFourthActivity使用透明主题的普通Activity,并新建4个布局文件,布局文件很简单,不再贴出布局文件中的代码,然后覆写相关的生命周期的方法,下面是MainActivity代码:

class MainActivity : Activity() {

    private var button1:Button? = null
    private var button2:Button? = null
    private var button3:Button? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        button1 = findViewById(R.id.button1)
        button2 = findViewById(R.id.button2)
        button3 = findViewById(R.id.button3)
        button1?.setOnClickListener {
            val intent = Intent(this,SecondActivity::class.java)
            startActivity(intent)
        }
        button2?.setOnClickListener {
            val intent = Intent(this,ThirdActivity::class.java)
            startActivity(intent)
        }
        button3?.setOnClickListener {
            val intent = Intent(this,FourthActivity::class.java)
            startActivity(intent)
        }
        println("MainActivity->onCreate")
    }

    override fun onStart() {
        super.onStart()
        println("MainActivity->onStart")
    }

    override fun onRestart() {
        super.onRestart()
        println("MainActivity->onRestart")
    }

    override fun onResume() {
        super.onResume()
        println("MainActivity->onResume")
    }

    override fun onPause() {
        super.onPause()
        println("MainActivity->onPause")
    }

    override fun onStop() {
        super.onStop()
        println("MainActivity->onStop")
    }

    override fun onDestroy() {
        super.onDestroy()
        println("MainActivity->onDestroy")
    }
}

然后是SecondActivity里面的代码:

class SecondActivity : Activity() {

    private var button2: Button? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)
        button2 = findViewById(R.id.button2)
        button2?.setOnClickListener{
            finish()
        }
        println("SecondActivity->onCreate")
    }

    override fun onStart() {
        super.onStart()
        println("SecondActivity->onStart")
    }

    override fun onRestart() {
        super.onRestart()
        println("SecondActivity->onRestart")
    }

    override fun onResume() {
        super.onResume()
        println("SecondActivity->onResume")
    }

    override fun onPause() {
        super.onPause()
        println("SecondActivity->onPause")
    }

    override fun onStop() {
        super.onStop()
        println("SecondActivity->onStop")
    }

    override fun onDestroy() {
        super.onDestroy()
        println("SecondActivity->onDestroy")
    }
}
  1. 首次运行程序,得到以下输出:
  2. 按下Home键后,再次点击应用图标后,得到以下输出:
  3. 按下返回键后,得到以下输出:
  4. 重新运行程序,点击button1按钮后,跳转到SecondActivity,得到以下输出:
  5. 点击SecondActivity中的按钮后,得到以下输出:
  6. 重新运行程序,点击button2按钮后,弹出Dialog形式的ThirdActivity,得到以下输出:
  7. 点击ThirdActivity中的按钮后,得到以下输出:
  8. 重新运行程序,点击button3按钮后,显示透明主题的Activity,得到以下输出:
  9. 点击FourthActivity中的按钮后,得到以下输出:

四.生命周期方法说明(《Android开发艺术探索》)

onCreate()

这是生命周期的第一个方法,表示Activity正在创建,在这个方法中,我们可以做一些初始化操作,比如加载布局资源、初始化Activity相关数据等。

onStart()

表示Activity正在被启动即将开始,这时Activity已经可见了,只不过还没有出现在前台,无法和用户进行交互。可以理解为Activity已经显示出来了,但是用户看不到。

onRestart()

表示Activity正在重新启动,一般情况下,当Activity从不可见状态重新变为可见状态后,此方法就会被回调,这种情形一般都是用户行为所导致的,比如用户按下Home键后或者打开了一个新的Activity,接着又回到了这个Activity,就会出现这种情况。

onResume()

表示Activity已经可见了,并且出现在前台开始活动,可以和用户进行交互。需要注意onStartonResume的对比,二者都表示Activity可见,但是onStart表示Activity在后台并且无法和用户进行交互,而onResume表示Activity已经显示在前台,可以和用户进行交互。

onPause()

表示Activity正在被停止,此时可以做一些数据存储、动画停止等,但不能是耗时的操作。一般情况下会接着回调onStop方法,如果此时再次回到这个Activity后,会接着回调onResume方法。但也有特殊情况,比如显示一个以Activity形式的Dialog或者采用了透明主题就不会回调onStop方法。

onStop()

表示Activity正在被停止,此时Activity变得不可见,在这个方法中可以做一些稍微重量级的回收工作,但也不能太耗时。

onDestroy()

表示Activity正在被销毁,这是Activity生命周期的最后一个方法,在这个方法中,我们可以做回收工作和一些资源的释放。

总结

从整个生命周期来说,onCreate()onDestroy()是配对的,表示Activity的创建和销毁,并且只能回调一次;onStart()onStop()是配对的,这是从Activity是否可见来说的,随着用户的操作和屏幕的点亮或者熄灭,这2个方法会回调多次;onResume()onPause()是配对的,这是从Activity是否在前台来说的,随着用户的操作和屏幕的点亮或者熄灭,这2个方法会回调多次。onStart()+onStop()onResume()+onPause(),这两组回调方法表示的意义不同,onStart()+onStop()是从Activity是否可见这个角度来回调的,onResume()+onPause()是从Activity是否位于前台这个角度来回调的,除了这种区别,在实际使用中并没有其他明显区别。

五.其他情况生命周期回调

锁屏

锁屏后,如果当前Activity没有被系统回收,就是普通的切换到不可见状态;如果被系统回收后,会销毁当前Activity,然后重新创建一个。

旋转屏幕(程序运行时,默认都是竖屏)

  1. 未在Manifest中进行设置,竖屏切到横屏(横屏再切回到竖屏,输出是和下面一样的,也就是说会回调2次):
    可以看出旋转屏幕后,Activity被销毁,然后重新创建,此时就算重写了onConfigurationChanged方法,也不会调用此方法
  2. Manifest中设置MainActivityconfigChanges="orientation|screenSize",并重写onConfigurationChanged方法,会得到以下输出:
  • 竖屏切到横屏:
    可以看到,Activity并没有销毁,而是回调了onConfigurationChanged方法
  • 横屏切回到竖屏:
    可以看到,Activity也没有被销毁,也是回调了onConfigurationChanged方法

故从以上可以知道,配置configChanges="orientation|screenSize"可以阻止Activity的销毁与重新创建,如果少了其中的任何一个,都会导致Activity的销毁。

  • configChanges常用属性值的相关说明:
属性值 说明
locale 用户所在区域发生变化,一般是用户切换了语言
keyboardHidden 键盘的可用性发生了改变,比如调出或隐藏了键盘
fontScale 字体比例发生了变化
orientation 屏幕方向发生了变化
screenSize 屏幕尺寸发生了变化

更多的属性值,直接截取《Android开发艺术探索》中的图:

保存数据

屏幕方向发生了旋转,或者Activity由于资源内存不足被系统杀死等异常销毁,并且有机会重新显示,系统会回调两个方法:onSaveInstanceState(outState:Bundle?)onRestoreInstanceState(savedInstanceState:Bundle?)。如果在EditText或者其他控件中有值的话,可以在onSaveInstanceState方法中,调用Bundle对象的相关putXxx方法进行存储,然后在onRestoreInstanceState方法或者onCreate中调用BundlegetXxx方法进行获取对应的值,一般我们推荐在onCreate中进行获取。注意:在正常的生命周期中并不会回调这两个方法

项目地址: github.com/leewell5717…

六. 总结

本文对Activity生命周期的基础做了一些讲述,生命周期对于我们来说是非常重要的,也有许多面试官喜欢问关于生命周期的基础,可能本文总结的不是很全面,或者有错误的地方,欢迎指出,也欢迎给我一些建议,我将在后面的写作中提升自己。