Android第一行代码学习笔记七---活动的生命周期
@1.返回栈
Android中的活动是可以层叠的,我们每启动一个新的活动,就会覆盖在原活动之上,然后点击Back键就会销毁最上面的活动,下面一个活动就会重新显示出来。
Android是使用任务(Task)来管理活动的,一个任务就是一组存放在栈里的活动的集合,这个栈也被称为返回栈(Back Stack)。栈是一种后进先出的数据结构,在默认情况下,每当我们启动了一个新的活动,它会在返回栈中入栈,并处于栈顶的位置。而当我们按下Back键或调用finish()方法去销毁一个活动时,处于栈顶的活动会出栈,这时前一个入栈的活动就会重新处于栈顶的位置。系统总是会显示处于栈顶的活动给用户。
@2.活动状态:每个活动在其生命周期中最多可能会有4种状态。
a:运行状态:当一个活动位于返回栈的栈顶时,这时活动就处于运行状态。系统最不愿意回收的就是处于运行状态的活动,因为这会带来非常差的用户体验。
b:暂停状态:当一个活动不再处于栈顶位置,但仍然可见时,这时活动就进入了暂停状态。这是因为并不是每一个活动都会占满整个屏幕,比如对话框形式的活动只会占用屏幕中间的部分区域。处于暂停状态的活动仍然是完全存活的,系统也不愿意回收这种活动,只有在内存极低的状况下,系统才会考虑去回收这种活动。
c:停止状态:当一个活动不再处于栈顶位置,并且完全不可见的时候就进入了停止状态。系统仍然会为这种活动保存相应的状态和成员变量,但是这并不是完全可靠的,当其它地方需要内存时,处于停止状态的活动有可能会被系统回收。
d:销毁状态:当一个从返回栈中移除后就变成了销毁状态。系统会最倾向于回收处于这种状态的活动,从而保证手机的内存充足。
@3:活动的生存期.
Activity类定义了7个回调方法,覆盖了活动生命周期的每一个环节
@1-onCreate():每个活动中都重写了这个方法,它会在活动第一次被创建的时候调用,你应该在这个方法中完成活动的初始化操作,比如说加载布局、绑定事件。
@2-onStart():这个方法在活动由不可见变为可见的时候调用。、
@3-onResume():这个活动早活动准备好和用户进行交互的时候调用。此时的活动一定位于返回栈的栈顶,并且处于运行状态。
@4-onPause():这个方法在系统准备去启动或者恢复另一个活动的时候调用。我们通常会在这个方法中将一些消耗CPU的资源释放掉,以及保存一些关键数据,但这个方法的执行速度一定要快,不然会影响到新的栈顶活动的使用。
@5-onStop():这个方法在活动完全不可见的时候调用。它和onPause()方法的区别在于,如果启动的新活动是一个对话框式的活动,那么onPause()方法会得到执行,而onStop()方法并不会执行。
@6-onDestroy():这个方法在活动被销毁之前调用,之后活动的状态变为销毁状态。
@7-onRestart():这个方法在活动由停止状态变为运行状态之前调用,也就是活动被重新启动了。
以上7个方法中除了onRestart()方法外,其它都是两两相对,从而又可以将活动分为3中生存期。
完整生存期:活动在onCreate()和onDestroy()之间所经历的,就是完整生存期,一般情况下,一个活动会在onCreate()方法中完成各种初始化操作,而在onDestroy()方法中完成释放内存的操作。
可见生存期:活动在onStart()和onStop()之间所经历的就是可见生存期,在可见生存期内活动对用户是可见的,即便有可能无法和用户交互。
前台生存期:活动在onResume()方法和onPause()方法之间经历的就是前台生存期。在前台生存期内,活动总是处于运行状态的,此时的活动是可以和用户进行交互的,我们平时看到和接触最多的也就是这个状态下的活动。
@4.体验活动的生命周期
新建ActivityCycleTest项目,子活动NormalActivity和DialogActivity,子活动布局为normal_layout和dialog_layout,编辑normal_layout.xml文件,将里面的内容替换成如下内容:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="this is a normal Activity"/>
</LinearLayout>
编辑dialog_layout.xml文件,将里面的内容替换成如下内容:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="this is a dialog Activity"/>
</LinearLayout>
修改AndroidManifest.xml的<activity>标签的配置如下:
<activity android:name=".DialogActivity"
android:theme="@android:style/Theme.Dialog">
/activity>
修改activity_main.xml,在LinearLayout中加入了两个按钮,一个用于启动NormalActivity,一个启动DialogActivity。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/start_normal_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Start Normal Activity"/>
<Button
android:id="@+id/start_dialog_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Start Dialog Activity"/>
</LinearLayout>
修改MainActivity中的代码:
public class MainActivity extends AppCompatActivity {
public static final String TAG="MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button startNormalActivity=(Button)findViewById(R.id.start_normal_activity);
final Button startDialogActivity=(Button)findViewById(R.id.start_dialog_activity);
startNormalActivity.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent =new Intent(MainActivity.this,NormalActivity.class);
startActivity(intent);
}
});
startDialogActivity.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(TAG,"onStart");
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG,"onResume");
}
@Override
protected void onPause() {
super.onPause();
Log.d(TAG,"onPause");
}
@Override
protected void onStop() {
super.onStop();
Log.d(TAG,"onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG,"onDestroy");
}
@Override
protected void onRestart() {
super.onRestart();
Log.d(TAG,"onRestart");
}
}
运行程序,观察logcat的打印日志,MainActivity第一次创建时会执行onCreate()、onStart()、和onResume()方法
点击第一个按钮启动NormalActivity,由于NormalActivity已经完全遮挡住MainActivity,因此onPause()和onStop()方法都会执行
back键回到MainActivity,由于之前MainActivity已经进入了停止状态,所以onRestart方法会得到执行,之后一次执行onStart()和onResume()方法,此时onCreate(0方法不会执行,因为MainActivity并没有重新创建
点击第二个按钮启动DialogActivity,只有onPause(0方法得到执行,onStop()方法并没有执行,因为DialogActivity并没有完全遮挡住MainActivity,此时MainActivity只是进入了暂停状态,并没有进入停止状态。相应的按下back键只有onResume()方法得到执行