Acitivity和Fragment的生命周期研究
前言
先分别研究界面跳转、对话框的弹出、返回键、home键、锁屏与解锁对Activity和Fragment各自的生命周期影响。之后研究在activity中使用fragment时activity生命周期变化对fragment生命周期的影响。最后研究使用android的Viewpager在设置缓存和不设置缓存的情况下对两者生命周期的影响。
一、 Activity的生命周期
Activity生命周期图
<1> 四种状态
1.活动(Active/Running)状态
当Activity运行在屏幕前台(处于当前任务活动栈的最上面),此时它获取了焦点能响应用户的操作,属于运行状态,同一个时刻只会有一个Activity 处于活动(Active)或运行(Running)状态
2.暂停(Paused)状态
当Activity失去焦点但仍对用户可见(如在它之上有另一个透明的Activity或Toast、AlertDialog等弹出窗口时)它处于暂停状态。暂停的Activity仍然是存活状态(它保留着所有的状态和成员信息并保持和窗口管理器的连接),但是当系统内存极小时可以被系统杀掉
3.停止(Stopped)状态
完全被另一个Activity遮挡时处于停止状态,它仍然保留着所有的状态和成员信息。只是对用户不可见,当其他地方需要内存时它往往被系统杀掉
4.非活动(Dead)状态
Activity 尚未被启动、已经被手动终止,或已经被系统回收时处于非活动的状态,要手动终止Activity,可以在程序中调用"finish"方法。
如果是(按根据内存不足时的回收规则)被系统回收,可能是因为内存不足了
内存不足时,Dalvik 虚拟机会根据其内存回收规则来回收内存:
(1)先回收与其他Activity 或Service/Intent Receiver 无关的进程(即优先回收独立的Activity)因此建议,我们的一些(耗时)后台操作,最好是作成Service的形式
(2).不可见(处于Stopped状态的)Activity
(3)Service进程(除非真的没有内存可用时会被销毁)
(4)非活动的可见的(Paused状态的)Activity
(5)当前正在运行(Active/Running状态的)Activity
<2> 7个重要方法
当Activity从一种状态进入另一状态时系统会自动调用下面相应的方法来通知用户这种变化,当Activity第一次被实例化的时候系统会调用,整个生命周期只调用1次,这个方法常用于初始化设置:
1、为Activity设置所要使用的布局文件
2、为按钮绑定监听器等静态的设置操作
onCreate(BundlesavedInstanceState);
当Activity可见未获得用户焦点不能交互时系统会调用
onStart();
当Activity已经停止然后重新被启动时系统会调用
onRestart();
当Activity可见且获得用户焦点能交互时系统会调用
onResume();
当系统启动另外一个新的Activity时,在新Activity启动之前被系统调用保存现有的Activity中的持久数据、停止动画等,这个实现方法必须非常快。当系统而不是用户自己出于回收内存时,关闭了activity 之后。用户会期望当他再次回到这个activity 的时候,它仍保持着上次离开时的样子。此时用到了onSaveInstanceState(),方法onSaveInstanceState()用来保存Activity被杀之前的状态,在onPause()之前被触发,当系统为了节省内存销毁了Activity(用户本不想销毁)时就需要重写这个方法了,当此Activity再次被实例化时会通过onCreate(Bundle savedInstanceState)将已经保存的临时状态数据传入因为onSaveInstanceState()方法不总是被调用,触发条件为(按下HOME键,按下电源按键关闭屏幕,横竖屏切换情况下),你应该仅重写onSaveInstanceState()来记录activity的临时状态,而不是持久的数据。应该使用onPause()来存储持久数据。
onPause();
当Activity被新的Activity完全覆盖不可见时被系统调用
onStop();
当Activity(用户调用finish()或系统由于内存不足)被系统销毁杀掉时系统调用,(整个生命周期只调用1次)用来释放onCreate()方法中创建的资源,如结束线程等
onDestroy();
<3> 3个嵌套循环
1.Activity完整的生命周期:从第一次调用onCreate()开始直到调用onDestroy()结束
2.Activity的可视生命周期:从调用onStart()到相应的调用onStop()
在这两个方法之间,可以保持显示Activity所需要的资源。如在onStart()中注册一个广播接收者监听影响你的UI的改变,在onStop() 中注销。
3.Activity的前台生命周期:从调用onResume()到相应的调用onPause()。
<4> demo:界面跳转、对话框、返回键、Home键、横竖屏切换对activity生命周期的影响
这个工程有两个activity,第一个activity中有两个按钮,一个按钮是弹出对话框,一个按钮时条换到第二个activity,通过log来观察两个activity的生命周期的变化
MainActivity.java
public classMainActivity extends Activityimplements OnClickListener{
privateButtonjump,showdialog;
@Override
protected void onCreate(BundlesavedInstanceState) {
Log.v("tag", "activity 1 onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
jump=(Button)findViewById(R.id.jump);
showdialog=(Button)findViewById(R.id.showdialog);
jump.setOnClickListener(this);
showdialog.setOnClickListener(this);
}
@Override
protected void onDestroy() {
Log.v("tag", "activity 1 onDestroy");
super.onDestroy();
}
@Override
protected void onPause() {
Log.v("tag", "activity 1 onPause");
super.onPause();
}
@Override
protected void onRestart() {
Log.v("tag", "activity 1 onRestart");
super.onRestart();
}
@Override
protected void onResume() {
Log.v("tag", "activity 1 onResume");
super.onResume();
}
@Override
protected void onStart() {
Log.v("tag", "activity 1 onStart");
super.onStart();
}
@Override
protected void onStop() {
Log.v("tag", "activity 1 onStop");
super.onStop();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.jump:
Intentintent =new Intent(MainActivity.this , TestActivity1.class);
startActivity(intent);
break;
case R.id.showdialog:
newAlertDialog.Builder(MainActivity.this).setTitle("弹出对话框").setPositiveButton("确定",null).show();
break;
}
}
}
Test1Activity.java
public classTestActivity1 extends Activity {
@Override
protected void onCreate(BundlesavedInstanceState) {
Log.v("tag", "activity 2 onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_activity1);
}
@Override
protected void onDestroy() {
Log.v("tag", "activity 2 onDestroy");
super.onDestroy();
}
@Override
protected void onPause() {
Log.v("tag", "activity 2 onPause");
super.onPause();
}
@Override
protected void onRestart() {
Log.v("tag", "activity 2 onRestart");
super.onRestart();
}
@Override
protected void onResume() {
Log.v("tag", "activity 2 onResume");
super.onResume();
}
@Override
protected void onStart() {
Log.v("tag", "activity 2 onStart");
super.onStart();
}
@Override
protected void onStop() {
Log.v("tag", "activity 2 onStop");
super.onStop();
}
}
程序刚运行时:
activiy 1 oncreate -> activity 1 onstart -> activity onresume
点击弹出对话框按钮,发觉log没有任何变化
点击跳转按钮跳转到第二个activity
activity 1 onpause -> activity 2oncreate -> activity 2 onstart -> activity 2 onresume -> activity 1 onstop
按下返回键返回第一个activity
activity 2 onpause -> activity 1onrestart -> activity 1 onstart -> activity 1 onresume -> activity 2onstop -> activity 2 ondestroy
注意:当点击返回的时候,这里调用的不是FirstActivity的onCreate()方法而是onRestart()方法,因为在之前FirstActivity已经被创建过了并且没有销毁,只要当FirstActivity销毁了再调用FirstActivity的时候才会调用onCreate()方法。
按下home键
activity 1 onpause ->