Android activity生命周期
这篇博客主要包含以下知识点:
activity介绍、 activity生命周期的详细过程(不同情况下的变化以及状态的改变)、finish和onDestory方法的关系、onSaveInstanceState和OnRestoreInstanceState的用法
Activity介绍:
Activity就是布满整个窗口或者悬浮于其他窗口上的交互界面。在一个应用程序中通常由多个Activity构成,都会在Manifest.xml中指定一个主的Activity,如下设置
<actionandroid:name="android.intent.action.MAIN" />
当程序第一次运行时用户就会看这个Activity,这个Activity可以通过启动其他的Activity进行相关操作。当启动其他的Activity时这个当前的这个Activity将会停止,新的Activity将会压入栈中,同时获取用户焦点,这时就可在这个Activity上操作了。都知道栈是先进后出的原则,那么当用户按Back键时,当前的这个Activity销毁,前一个Activity重新恢复。
生命周期的详细过程:
onCreate ---> onStart ---> onResume --->(切到后台,按下Home键) onPause---> onSaveInstanceState ---> onStop --->(从后台切回来)onRestart ---> onStart ---> onResume --->(横屏切换)onPause ---> onSaveInstanceState--->onStop --->onDestory--->onCreate--->onStart--->OnRestoreInstanceState--->onResume--->(back键)finsh --->onPause--->onStop--->onDestory
注: 横屏切换这种操作类似于干掉之前的activity,重新创建一个activity,所以会出现onSaveInstanceState--->onStop--->onDestory---这条线
其中onSaveInstanceState是保存当前的一些状态;OnRestoreInstanceState是恢复之前保存的状态;
ps : 图出自于云课堂老师的课件中,在此引用方便记录
下面举例说明一下finish和onDestory方法的关系:
MainActivity.java
@Override public void finish() { Log.i("Activity LifeCycle", "finish...1 was called"); //super.finish(); Log.i("Activity LifeCycle", "finish...2 was called"); } @Override protected void onDestroy() { Log.i("Activity LifeCycle", "onDestroy...1 was called"); super.onDestroy(); Log.i("Activity LifeCycle", "onDestroy...2 was called"); }
注释掉super.finish(); 启动app,然后按下back键,日志打印结果如下:
不注释super.finish(),启动app, 然后按下back键,日志打印结果如下:
经过对比发现:
finish()方法用于结束一个Activity的生命周期,在你的activity动作完成的时候,或者Activity需要关闭的时候,调用此方法。
当你调用此方法的时候,系统只是将最上面的Activity移出了栈,并没有及时的调用onDestory()方法,其占用的资源也没有被及时释放。因为移出了栈,所以当你点击手机上面的“back”按键的时候,也不会再找到这个Activity。即在finish()中的super调用了ondestory()的都函数;如果注释掉finish中的super方法,发现并不会触发onDestory方法;
而onDestory()方法则是Activity的一个生命周期方法,其作用是在一个Activity对象被销毁之前,Android系统会调用该方法,用于释放此Activity之前所占用的资源。
finish会调用到onDestroy方法;
这里讲解一下onSaveInstanceState和OnRestoreInstanceState的用法:
比如你想保存一个实例变量的值,而在切换横竖屏的时候导致这个变量值更改了,不是你想要的值,此时心里肯定是,什么鬼?啥情况?一堆黑人问号脸?
原因则是因为横屏这种操作实际上是销毁了一个activity,重新创建了一个activity, 而两个activity不是同一个activity, 那对应的实例变量当然也就不同啦!!!比如:
我们发现横屏之后,得分栏为空,这不是我们想要的结果。
解决方法如下:在onSaveInstanceState中保存实例变量得分, 在onRestoreInstanceState中拿到实例变量的值;
@Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt("score", score); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); score = savedInstanceState.getInt("score"); TextView scoreTextView = findViewById(R.id.scoreTextView); scoreTextView.setText("得分: " + score); }
如下如结果所示没横屏之后分数栏并没有回到初始值0,而是保存了状态。
此时有小伙伴就要问了,为什么上面的单词以及选项会变呢,之前已经说过,横屏之后会重新创建一个activity, 而单词以及选项是随机产生的,所以会改变,
而且我们在这里也没有保存单词以及选项的状态,只是保存了得分的状态!有兴趣的小伙伴可以自己试着保存一下单词以及得分的状态!