Android——生命周期的返回栈、活动状态、生存期
作者:互联网
1.返回栈
- 可以知道,Android中的活动是可以层叠的,每启动一个新的活动,就会覆盖在原来的活动之上,然后点击back键会销毁最上面的活动,下面的一个活动就会重新显示出来
- Android是使用任务(Task)来管理活动的,一个活动就是一组存放在栈里的活动的集合,这个栈也被称作返回栈(Back Stack)
- 栈是一种后进先出的活动,它会在返回栈中入栈,并处于栈顶的位置。
- 每当按下Back键或者调用finish()方法去销毁一个活动时,处于栈顶的活动会出栈,这时前一个入栈的活动就会重新处于栈顶的位置。
- 系统总是显示处于栈顶的活动给用户
- 返回栈示意图:
2.活动状态
每个活动在其生命周期中最多可能会有4种状态。
- 运行状态:
- 当一个活动位于返回栈的栈顶时,这时活动就处于运行状态。系统最不愿意回收处于运行状态的活动,因为这会带来非常差的用户体验
- 暂停状态:
- 当一个活动不再处于栈顶位置,但仍然可见时,这时活动就进入了暂停状态。
- 问题:既然已经不处于栈顶,为什么会可见:
- 因为并不是每一个活动都会占满整个屏幕的,比如对话框形式的活动只会占用屏幕中间的部分区域
- 处于暂停状态的活动仍然是完全存活着的,系统也不愿意回收(用户体验问题)
- 只有在内存极低的情况下,系统才会考虑去回收这种活动
- 停止状态:
- 当一个活动不再处于栈顶位置,并且完全不可见时,就进入了停止状态
- 系统仍然会为这种活动保存相应的状态和成员变量,但是这并不是完全可靠的,当其他地方需要内存时,处于停止状态的活动有可能会被系统回收
- 销毁状态:
- 当一个活动从返回栈种移除后就变成了销毁状态。系统会最倾向于回收处于这种状态的活动,从而保证手机的内存充足
3.活动的生存期
Activity类中定义了7个回调方法,覆盖了活动生命周期的每一个环节:
- onCreate()
- 在活动第一次被创建的时候调用。可以用来完成活动的初始化操作:如加载布局、绑定事件
- onStart()
- 活动由不可见变为可见的时候调用
- onResume()
- 这个方法在活动准备好和用户进行交互的时候调用。此时的活动一定位于返回栈的顶端,且处于运行状态
- onPause()
- 这个方法在系统准备去启动或者恢复另一个活动的时候调用。
- 通常会在这个方法中将一些消耗CPU的资源释放掉,以及保存一些关键数据
- 但这个方法的执行速度一定要块,不然会影响到新的栈顶活动的使用
- onStop()
- 这个方法在活动完全不可见的时候调用。
- 和onPause()方法的主要区别在于:如果启动的新活动是一个对话框式的活动,那么onPause()方法会得到执行,而onStop()方法并不会执行
- onDestory()
- 这个方法在活动被销毁之前执行,之后的活动状态将变为销毁状态
- onRestart()
- 这个方法在活动由停止状态变为运行状态之前调用,也就是活动被重新启动了
以上7个方法中除了onRestart()方法,其他的都是两两对应,从而又可以将活动分为三种生存期:
- 完整生存期:onCreate()+onDestory()之间所经历的
- 一般情况下,一个活动会在onCreate()方法中完成各种初始化操作,
- 而在onDestory()方法中完成释放内存的操作
- 可见生存期:活动在onStart()+onStop()方法之间所经历的
- 在可见生存期内,活动对用户总是可见的,即便有可能无法和用户进行交互。
- 可以通过这两个方法,合理的管理哪些对于用户可见的资源。如:
- 在onStart()方法中对资源进行加载
- 在onStop()方法中对资源进行释放
- 从而保证处于停止状态的活动不会占用过多内存
- 前台生存期:活动在onResume()+onPause()方法之间的经历:
- 在前台生存期内,活动总是处于运行状态的,此时的活动是可以和用户进行交互的,平时看到和接触最多的也就是这个状态下的活动
生命周期图示:
官方:中文:
4.代码示例:
一个主活动,一个普通全屏活动,一个Dialog活动
主活动——有两个按钮,分别打开普通活动和Dialog活动,并且在所有的生命周期中都有相应信息打印:
package com.example.activitylifecycletest; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d("onCreate============: ","onCreated"); // 打开NormalActivity Button startNormal=(Button) findViewById(R.id.start_normal_activity); final Button startDialog=(Button) findViewById(R.id.start_dialog_activity); startNormal.setOnClickListener(new View.OnClickListener() { @Override // 打开NormalActivity public void onClick(View view) { Intent intent=new Intent(MainActivity.this,NormalActivity.class); startActivity(intent); } }); startDialog.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent=new Intent(MainActivity.this,DialogActivity.class); startActivity(intent); } }); } // 所有生命周期方法 @Override protected void onStart(){ super.onStart(); Log.d("onStart============: ","onStart"); } @Override protected void onResume(){ super.onResume(); Log.d("onResume============: ","onResume"); } @Override protected void onPause(){ super.onPause(); Log.d("onPause============: ","onPause"); } @Override protected void onStop(){ super.onStop(); Log.d("onStop============: ","onStop"); } @Override protected void onDestroy(){ super.onDestroy(); Log.d("onDestroy============: ","onDestroy"); } @Override protected void onRestart(){ super.onRestart(); Log.d("onRestart============: ","onRestart"); } }
(1)首次启动应用程序:
入口活动一共执行了三个方法里的代码:
- onCreate()
- onStart()
- onResume()
(2)打开第一个普通全屏活动
入口活动又执行了:
- onPause()
- onStop()
- 由于打开的活动已经把MainActivity完全遮住了,所以这两个方法都会执行
(3)按下back键返回入口程序
入口程序又执行了
- onRestart()——由于之前MainActivity已经进入了停止状态,所以onRestart()会执行
- onStart()
- onResume()
- 此时不会执行onCreate()方法,因为MainActivity并没有重新创建
(4)继续启动DialogActivity
执行了:
- onPause()
- dialog活动并没有遮住MainActivity,所以不会执行onStop()
(5)返回MainActivity
此时执行了:
- onResume()
(6)退出MainActivity
(5)活动被回收了怎么办
- 前面我们已经说过,当一个活动进入到了停止状态,是有可能被系统回收的。那么想象以下场景∶应用中有一个活动A,用户在活动A的基础上启动了活动B,活动A就进入了停止状态,这个时候由于系统内存不足,将活动A回收掉了,然后用户按下 Back键返回活动A,会出现什么情况呢?其实还是会正常显示活动A的,只不过这时并不会执行onRestart()方法,而是会执行活动A的 onCreate()方法,因为活动A在这种情况下会被重新创建一次。
- 这样看上去好像一切正常,可是别忽略了一个重要问题,活动 A中是可能存在临时数据和状态的。打个比方,MainActivity中有一个文本输人框,现在你输入了一段文字,然后启动NormalActivity,这时MainActivity由于系统内存不足被回收掉,过了一会你又点击了Back键回钊MainActivity,你会发现刚刚输人的文字全部都没了,因为MainActvity被重新创建了。
- 解决办法:onSaveInstanceState()回调方法
标签:状态,MainActivity,活动状态,生存期,onPause,onStop,Android,活动,方法 来源: https://www.cnblogs.com/codexlx/p/13566221.html