1、Activity概述
- Activity是向用户展示信息并提供交互功能的界面
- 四大组件之一,一个APP中可以有0或者多个Activity
- 在Activity中按下返回键,当前Activity会被销毁
- 当前Activity启动其它Activity,当当前Activity不会被销毁,会被压入Activity栈中
- 可以跳转其它app的Activity
2、Activity生命周期的两种情况
(1)典型情况下的生命周期:在有用户参与的情况下,Activity所经过的生命周期的改变
(2)异常情况下的生命周期:内存不够时Activity被系统回收或者由于当前设备的configuration发生改变从而导致Activity被销毁而重建
3、Activity生命周期
其实Android 是使用任务(Task)来管理活动的,一个任务就是一组存放在栈里的活动 的集合,这个栈也被称作返回栈(Back Stack)。栈是一种后进先出的数据结构,在默认情况 下,每当我们启动了一个新的活动,它会在返回栈中入栈,并处于栈顶的位置。而每当我们 按下Back 键或调用finish()方法去销毁一个活动时,处于栈顶的活动会出栈,这时前一个入 栈的活动就会重新处于栈顶的位置。系统总是会显示处于栈顶的活动给用户。
(1)活动状态
每个活动在其生命周期中最多可能会有四种状态。
1. 运行状态
当一个活动位于返回栈的栈顶时,这时活动就处于运行状态。
2. 暂停状态
当一个活动不再处于栈顶位置,但仍然可见时,这时活动就进入了暂停状态。
3. 停止状态
当一个活动不再处于栈顶位置,并且完全不可见的时候,就进入了停止状态。系统 仍然会为这种活动保存相应的状态和成员变量,但是这并不是完全可靠的,当其他地方 需要内存时,处于停止状态的活动有可能会被系统回收。
4. 销毁状态
当一个活动从返回栈中移除后就变成了销毁状态。系统会最倾向于回收处于这种状 态的活动,从而保证手机的内存充足。
(2)活动的生存期
Activity 类中定义了七个回调方法,覆盖了活动生命周期的每一个环节,下面我来介绍下这七个方法。
- onCreate()
这个方法你已经看到过很多次了,每个活动中我们都重写了这个方法,它会在活动 第一次被创建的时候调用。你应该在这个方法中完成活动的初始化操作,比如说加载布 局、绑定事件等。
2. onStart()
这个方法在活动由不可见变为可见的时候调用,但此时还无法和用户交互
3. onResume()
这个方法在活动准备好和用户进行交互的时候调用。此时的活动一定位于返回栈的 栈顶,并且处于运行状态。
4. onPause()
这个方法在系统准备去启动或者恢复另一个活动的时候调用。我们通常会在这个方 法中将一些消耗CPU的资源释放掉,以及保存一些关键数据,但这个方法的执行速度 一定要快,不然会影响到新的栈顶活动的使用。还是显示在界面上,只是没有焦点 。
5. onStop()
这个方法在活动完全不可见的时候调用。它和onPause()方法的主要区别在于,如 果启动的新活动是一个对话框式的活动,那么onPause()方法会得到执行,而 onStop() 方法并不会执行。
6. onDestroy()
这个方法在活动被销毁之前调用,之后活动的状态将变为销毁状态。activity.isFinishing()
7. onRestart()
这个方法在活动由停止状态变为运行状态之前调用,也就是活动被重新启动了。
以上七个方法中除了onRestart()方法,其他都是两两相对的,从而又可以将活动分为三 种生存期。
1. 完整生存期
活动在onCreate()方法和onDestroy()方法之间所经历的,就是完整生存期。一般情
况下,一个活动会在onCreate()方法中完成各种初始化操作,而在onDestroy()方法中完
成释放内存的操作。
2. 可见生存期
活动在onStart()方法和onStop()方法之间所经历的,就是可见生存期。在可见生存 期内,活动对于用户总是可见的,即便有可能无法和用户进行交互。我们可以通过这两 个方法,合理地管理那些对用户可见的资源。比如在onStart()方法中对资源进行加载, 而在onStop()方法中对资源进行释放,从而保证处于停止状态的活动不会占用过多内存。
3. 前台生存期
活动在onResume()方法和onPause()方法之间所经历的,就是前台生存期。在前台 生存期内,活动总是处于运行状态的,此时的活动是可以和用户进行相互的,我们平时 看到和接触最多的也这个状态下的活动。
(3)典型情况下的生命周期分析
- A-Activity —> B-Activity(普通活动)—> A-Activity
A-onCreate ---> A-onStart --> A-onResume --> A-onPause ---> B-onCreate ---> B-onStart --> B-onResume --> A-onStop--> B-onPause --> A-onRestart ---> A-onStart --> A-onResume --> B-onStop --> B-onDestroy
- A-Activity —> B-Activity(对话框式的活动 )—> A-Activity
A-onCreate ---> A-onStart --> A-onResume --> A-onPause ---> B-onCreate ---> B-onStart --> B-onResume --> A-onStop不会调用
--> B-onPause --> A-onResume --> B-onStop --> B-onDestroy
- 新Activity启动前,旧Activity的onPause先调用,新Activity再执行onCreate —> onStart–> onResume,这是为了防止跳转Activity时,屏幕上是黑屏,用户体验极差。
- 小结:onPause中不能做重量级操作、耗时操作,使新的Activity尽快显示出来并切换到前台。
(4)异常情况下的生命周期分析
系统配置改变导致Activity被杀死并重新创建
- 系统配置发生改变时:drawable中有不同的图片,横竖屏时,系统会去加载不同对应的图片,此时系统配置就会发生改变
- 配置改变后,Activity会被销毁,onPause –> -onStop –>
B-onDestroy,再重新创建新的Activity,onCreate —> onStart –> onResume - 但在调用onStop之前,系统会调用onSavaInstanceState(Bundle outState)来保存当前Activity的状态(此方法与onPause没有既定的时序关系,此方法只会出现在Activity被异常终止的情况下)
- 在Activity被重新创建onStart后,系统会调用onRestoreInstanceState(Bundle savedInstanceState)取出之前保存的数据
- Activity异常终止后的两种数据恢复
onCreate:正常启动Bundle为空,所以必须额外判断
onRestoreInstanceState:一旦被调用Bundle肯定有值
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState!=null) {
String data = savedInstanceState.getString("data");
Log.d("Amanda", "onCreate方法取出数据:"+data);
}
}
/**
* 1、只在Activity异常终止后会调用此方法
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.d("Amanda", "onSaveInstanceState");
outState.putString("data", "这是要恢复的数据");
}
/**
* 2、在Activity被重新创建onStart后,系统会调用
* onRestoreInstanceState(Bundle savedInstanceState)取出之前保存的数据
*/
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onRestoreInstanceState(savedInstanceState);
String data = savedInstanceState.getString("data");
Log.d("Amanda", "onRestoreInstanceState方法取出数据:"+data);
}
}
资源内存不足导致低优先级的Activity被杀死
- 此种情况下其数据储存与恢复情况与第一种情况一致
- Activity优先级:前台正在和用户交互的Activity > 可见但非前台的无法与用户直接交互的Activity >后台的Activity(执行了onStop)
- 因此一些后台程序最好放在四大组件中运行保证有一定的优先级,这样不会轻易被系统杀死
- 如何在屏幕旋转配置发生改变后,不重新创建Activity
android:configChanges="orientation|screenSize"//SDkVersion大于13需加screeSize
配置改变时调用的方法
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.d("Amanda", ""+newConfig);
}