Activity的生命周期
随着用户不断地在应用程序页面之间导航,Activity会在不同的生命周期状态之间切换;当某个Activity第一次被调用时,Android系统将会调用一系列的方法以启动用户界面;通过使用这些方法,你可以像创建其他组件一样创建Activity的外观和体验;
如果用户启动另一个Activity甚至切换到另一个应用程序,随着你的Activity进入后台,Android会调用一系列其他的方法;例如:如果用户切换到另一个应用程序,可能需要断开当前应用程序使用的所用数据连接;出现这些状况时,应用程序的状态可能会丢失;
如果Acticity在前台或在Activity栈的顶部,那么他会被认为是活动的(或可运行的);它在Android中具有最高的优先级,只有在极端情况下才会被操作系统终止;
Activity可以被暂停,而暂停状态在Android系统中拥有第二高的优先级;当Activity暂停时,所有的状态和成员信息都会被维护并保存到窗口管理器中;
Activity会被停止或隐藏到后台,这通常发生在一个Activity被另一个Activity完全覆盖时;这些Activity仍然视图保持其状态和成员信息,但是在Activity的三种状态中,优先级是最低的;
当某个Activity被Android系统从内存中移除时,你必须重新启动应用程序
综上所述, 你只需要通过简单地重写应用程序中的相关方法就可以处理Activity状态的改变;当Activity启动时,会调用onCreate()方法;在这个方法中,你可以创建视图、初始化变量和引进静态数据;但为了不降低这个处理过程的速度,代码中最好尽量少做类似的处理;
onStart方法在onCreate方法之后被调用;如果需要在Activity显示之前执行刷新当前视图之类的特定操作,onStart方法非常有用;当Activity准备好与用户交互时,onResume方法会被调用,此时你可以做诸如显示动画特效或相关对话框的处理;
onPause方法在系统即将把Activity放在后台运行或Activity部分被遮挡时被调用;你可以在这个方法里保存任何未保存的更改、清理消耗资源的对象、降低帧速率或停止动画;
onStop方法在Activity变为不可见时被调用;这个方法可能根本不会被调用,所以最好不要依赖它;
onDestroy方法是在Activity被销毁或被从内存中删除之前最后被调用的方法;它用于清理可能会造成资源泄露的过程,如任何后台线程;
onRestart方法在Activity已经停止、再次启动之前被调用;
再论Activity生命周期
如你所见,Activity只是Android应用程序的一个屏幕或者用户界面,他是与用户交互的一个全屏应用或者浮动窗口;Android应用程序由不同的Activity组成,这些Activity即与用户进行交互,也与其他的Activity进行交互;例如,一个简单的计算器仅使用单个Activity;如果完善计算器应用程序,使其在简单版本和科学版本之间切换,你将使用两个Activity;
每个Android应用程序都运行在单独的进程中;为了运行应用程序,进程不断地被启动和终止;为了节省内存和资源,进程可能会被杀掉;而Activity则轮流地运行在应用程序的UI主线程中;
Activity启动后就会进入一个生命周期(lifecycle);生命周期是一个术语,他指的是当用户(或者操作系统)与Activity交互时,Activity经历的状态;Android提供了特别的回调方法来让你针对Activity声明周期的变化做出反应;
Activity生命周期4种状态:
- 当Activity位于应用程序的前台时,他是运行中的Activity;在一段时间内只有一个Activity处于运行状态;
- 如果Activity失去焦点,但仍可见(比如一个更小的Activity出现在栈顶),那么Activity处于暂停状态;
- 如果Activityb被另一个运行中的Activity彻底覆盖,它将处于停止状态;当Activity停止时,将失去所有状态,这样就需要在重启Activity时,重新创建用户界面的当前状态;
- 当Activity被暂停或者停止后,系统为了回收内存可以结束他;在这之后用户可以重新启动Activity;
但应用程序在不同状态之间迁移时android.app.Activity的生命周期方法(或者回调)会被系统调用;这些回调方法如下:
- onCreate(Bundle savedInstanceState)在Activity第一次被创建时调用;此时应初始化数据、创建初始化视图或者恢复Activity之前被保存的冻结状态(稍后讨论);OnCreate之后通常是调用onStart;
- onStart()在Activity变为可见时被调用;这里最适合编写应用程序用户界面的相关代码,如处理与用户交互的事件;OnStart之后通常是调用onResume;但如果Activity变为隐藏的,那么将调用onStop;
- onResume()在Activity变为前台运行并且可以与用户交互时被调用;他之后通常是调用onPause;
- onpause()在其他Activity切换到前台时被调用;onPause的实现必须很快,因为在该函数返回前,其他Activity不能运行,如果Activity重新回到前台,那么onPause之后调用的是onResume;如果Activity变为不可见,那么onPause之后调用的是onStop;
- onStop在Activity变为不可见时被调用;无论是新Activity被启动(或者已经存在的Activity被恢复)还是当前Activity被销毁,当前Activity的onStop回调都会被调用;如果Activity重新回到前台,那么onStop之后将调用onRestart;
acenodie 于 2015/3/28 15:53 修改
接下来通过具体的实例来详细了解一下Android的生命周期:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer;
Log.d("Life", "onCreate");
}
public void onStart(){
super.onStart();
Log.d("Life", "onStart");
}
public void onPause(){
super.onPause();
Log.d("Life", "onPause");
}
public void onResume(){
super.onResume();
Log.d("Life", "onResume");
}
public void onStop(){
super.onResume();
Log.d("Life", "onStop");
}
public void onDestroy(){
super.onDestroy();
Log.d("Life", "onDestroy");
}
public void onRestart(){
super.onRestart();
Log.d("Life", "onRestart");
}
我想说的是,刚才为了去找一下Onenote有没有更好的代码高亮的插件一下花了近两个小时的时间,刚开始只是找一下有没有新推出的插件或我我还没用过的,可是都没有发现,又想能不能将Eclipse上的代码的格式复制下来,那样岂不是更好么,找到了两个方法,其中一个方法无效,另外一个太复杂还没有试;于是乎我就想到了Onenote2016,看有没有推出这一新功能,一搜便发现了onenote推出了新的网页剪辑插件clliper,简直神器呀,便开始捣鼓,但是官网的下载不了,于是乎群里去求助,无果,便打算去chrome插件商店,GFW,你懂得,打开goagen,依然无效,GFW真是日益强大,又想起了前几天买的VPN,GreenVPN,再次尝试,无效,再次问客服,不回!,去贴吧写了一封投诉贴,直接被管理员删除,问他原因,不回,举报了他,又在QQ上举报了一次,最后还是低声下气去贴吧问原因,至今无果,开始回来学习,时间就是这么一点一点浪费的 -_-|||,我甚至还打开了搜狗输入法找了一个表情!!哎哎!时间就是这么浪费的呀,这是在我自己把写的读完一次再次感受到的,什么都不说了,哎;
废话不说了,开始分析;
打开应用程序,首先依次执行的是onCreate、onStart、onResume,如下图:
当我点击旋转屏幕后,依次执行的是如下图黑色框内的部分,依次是:onPause、onStop、onDestroy、onCreate、onStart、onResume,可以发现,后三个和上面刚刚打开应用程序的执行的三个方法是一样的,现在可以理解为是又重新加载了一遍Actiity,详情还不太清楚,见后;
通过在网上(来自 <http://blog.csdn.net/liu_zhen_wei/article/details/8049018> )确认,在旋转屏幕的时候Activity的onDestroy和onCreate方法会被调用,意思就是这个Activity确实是被销毁然后重新创建的;
同时也有方法避免Activity在转屏时被销毁,原理还不清楚:
1)修改AndroidManifest.xml
在activity属性中加入:
android:configChanges="orientation|keyboardHidden"
- android:configChanges,这个方法主要是负责列出清单,当清单上用户指定的设置改变时,Activity会自己处理这些变化。
- orientation,屏幕界面旋转(可能是用户手动旋转的),【注意:如果你的开发API等级等于或高于13,你还需要设置screenSize,因为screenSize会在屏幕旋转时改变】
-
keyboardHidden,键盘辅助功能改变
如下:
<activity android:theme="@style/ContentOverlay"
android:launchMode="singleTask"
android:configChanges="keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustPan|stateAlwaysVisible" android:name="com.weibo.net.ShareActivity">
</activity>
当此时切换到另外一个应用程序时,依次执行方法:onPause、onStop;
当我再次切换回这个应用时,依次执行onRestart、onStart、onResume;
打开应用,然后点返回键,依次执行onPause、onStop、onDestroy
实验证明,当点返回键的时候程序已经执行完毕,这时候如果再从最近的任务里启动的话,相当于是重新打开了,而从最近的任务栏里删除记录,也不会有其他的回调函数被调用;
此时此刻我必须要记录一下,当我在调试这个定时器的时候,我点击Start开始计时后,setTimeDisplay()函数一直执行,这是正常情况;但是奇怪的是当我点返回键之后,这个函数并没有停止,而是继续执行,直到我在最近的任务栏里删除记录才停止。。。。。
奇了个怪了???
acenodie 于 2015/3/28 22:52 修改
等一下,上面还有一个测试没有做,就是在应用程序出现后,按主屏键回到主屏的情况,测试如下:
经测试这种情况下,和直接切换到其他应用程序的情况一样,依次执行onPause和onStop;
这里又发现了一个问题,因为按照理论的情况,Activity的生命周期的流程如下图,不同状态之间的切换是很多种情况的,而我上面所分析的情况里很明显是不包括下面的很多种情况的,例如:
从onPause --onCreate
从onStop --onCreate
从onPause -- onResume
从onStop --onCreate
这些情况希望能在以后的机会中测试到;