1.返回栈

可以知道,Android中的活动是可以层叠的,每启动一个新的活动,就会覆盖在原来的活动之上,然后点击back键会销毁最上面的活动,下面的一个活动就会重新显示出来

Android是使用任务(Task)来管理活动的,一个活动就是一组存放在栈里的活动的集合,这个栈也被称作返回栈(Back Stack)

栈是一种后进先出的活动,它会在返回栈中入栈,并处于栈顶的位置。

每当按下Back键或者调用finish()方法去销毁一个活动时,处于栈顶的活动会出栈,这时前一个入栈的活动就会重新处于栈顶的位置。

系统总是显示处于栈顶的活动给用户

返回栈示意图:

android 返回值 安卓返回栈_android 返回值

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()方法之间的经历:

在前台生存期内,活动总是处于运行状态的,此时的活动是可以和用户进行交互的,平时看到和接触最多的也就是这个状态下的活动

生命周期图示:

官方:

android 返回值 安卓返回栈_android_02

中文:

android 返回值 安卓返回栈_android 返回值_03

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)首次启动应用程序:

android 返回值 安卓返回栈_ide_04

入口活动一共执行了三个方法里的代码:

onCreate()
onStart()
onResume()

(2)打开第一个普通全屏活动

android 返回值 安卓返回栈_android 返回值_05

入口活动又执行了:

onPause()
onStop()

由于打开的活动已经把MainActivity完全遮住了,所以这两个方法都会执行

(3)按下back键返回入口程序

android 返回值 安卓返回栈_android_06

入口程序又执行了

onRestart()——由于之前MainActivity已经进入了停止状态,所以onRestart()会执行

onStart()
onResume()

此时不会执行onCreate()方法,因为MainActivity并没有重新创建

(4)继续启动DialogActivity

android 返回值 安卓返回栈_生命周期_07

执行了:

onPause()

dialog活动并没有遮住MainActivity,所以不会执行onStop()

(5)返回MainActivity

此时执行了:

onResume()

(6)退出MainActivity

android 返回值 安卓返回栈_android 判断活动栈_08

(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,活动,方法