Android学习笔记(六)
活动的生命周期
Android中的活动是可以重叠的,每启动一个新的活动,就会覆盖在原活动之上,然后点击Back键就会销毁最上面的活动。
Android是使用任务(Task)来管理活动的,一个任务就是一组存放在栈里的活动的集合,也被称为返回栈(Back Stack)。
每个活动在其生命周期中最多可能有四种状态:
1.运行状态
一个活动位于返回栈的栈顶时,这时活动就处于运行状态。
2.暂停状态
一个活动不再处于栈顶位置,但仍然可见,这时活动就进入了暂停状态。
3.停止状态
一个活动不再处于栈顶位置,并且完全不可见是时候,就进入了停止状态。
4.销毁状态
一个活动从返回栈中移除后就变成了销毁状态。
Activity类中定义了七个回调方法,覆盖了生命周期的每一个环节:
1.onCreate()方法
它会在活动第一次被创建时调用,在该方法中完成活动的初始化操作,例如加载布局,绑定事件等。
2.onStart()方法
该方法在活动由不可见变为可见时调用。
3.onResume()方法
该方法在准备好和用户进行交互的时候调用。
4.onPause()方法
该方法在系统准备去启动或者恢复另一个活动的时候调用。
5.onStop()方法
该方法在活动完全不可见时调用。它和onPause()方法的主要区别是,如果启动的新活动是一个对话框活动,onPause()方法会被调用,而onStop()方法不会执行。
6.onDestroy()方法
该方法在活动被销毁之前调用。
7.onRestart()方法
该方法在活动由停止状态变为运行状态之前调用,活动被重新启动。
附上Android官方提供的一张活动的生命周期示意图:
新建一个Android工程,新建时自动创建活动和布局。
新建一个normal_layout.xml文件,代码如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/normal_activity" /> </LinearLayout>
该布局中,简单使用一个TextView来显示一行文字。
在新建一个dialog_layout.xml文件,代码如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/dialog_activity" /> </LinearLayout>
然后新建NormalActivity继承自Activity,代码如下:
package com.gfeng.activitylifecycletest; import android.app.Activity; import android.os.Bundle; import android.view.Window; public class NormalActivity extends Activity { protected void onCreate (Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.normal_layout); } }
在NormalActivity类中加载normal_layout布局。
在新建一个DialogActivity继承自Activity,代码如下:
package com.gfeng.activitylifecycletest; import android.app.Activity; import android.os.Bundle; import android.view.Window; public class DialogActivity extends Activity { protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.dialog_layout); } }
在DialogActivity类中加载dialog_layout布局。
最后在AndroidManifest.xml文件中分别注册NormalActivity和DialogActivity活动。添加代码如下:
<activity android:name=".NormalActivity" > </activity> <activity android:name=".DialogActivity" android:theme="@android:style/Theme.Dialog" > </activity>
这里对两个活动的注册代码不同,DialogActivity使用了android:theme属性,用于给当前活动指定主题的。
下面修改activity_main.xml,重新定制主活动的布局,修改代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/start_normal_activity" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/start_normal_activity" /> <Button android:id="@+id/start_dialog_activity" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/start_dialog_activity" /> </LinearLayout>
在这里使用LinearLayout,加入两个按钮,一个用来启动NormalActivity,另一个用来启动DialogActivity。
然后修改MainActivity中的代码:
1 package com.gfeng.activitylifecycletest; 2 3 import android.app.Activity; 4 import android.content.Intent; 5 import android.os.Bundle; 6 import android.util.Log; 7 import android.view.View; 8 import android.view.View.OnClickListener; 9 import android.view.Window; 10 import android.widget.Button; 11 12 13 public class MainActivity extends Activity { 14 15 public static final String TGA = "MainActivity"; 16 17 @Override 18 protected void onCreate(Bundle savedInstanceState) { 19 super.onCreate(savedInstanceState); 20 Log.d(TGA, "onCreate"); 21 requestWindowFeature(Window.FEATURE_NO_TITLE); 22 setContentView(R.layout.activity_main); 23 Button startNormalActivity = (Button) findViewById(R.id.start_normal_activity); 24 startNormalActivity.setOnClickListener(new OnClickListener() { 25 26 @Override 27 public void onClick(View v) { 28 //显示Intent方法的使用 29 Intent intent = new Intent(MainActivity.this,NormalActivity.class); 30 startActivity(intent); 31 32 } 33 }); 34 35 Button startDialogActivity = (Button) findViewById(R.id.start_dialog_activity); 36 startDialogActivity.setOnClickListener(new OnClickListener() { 37 38 @Override 39 public void onClick(View v) { 40 //显示Intent方法的使用 41 Intent intent = new Intent(MainActivity.this,DialogActivity.class); 42 startActivity(intent); 43 44 } 45 }); 46 47 } 48 49 protected void onStart() { 50 super.onStart(); 51 Log.d(TGA, "onStart"); 52 } 53 54 protected void onResume() { 55 super.onResume(); 56 Log.d(TGA, "onResume"); 57 } 58 59 protected void onPause() { 60 super.onPause(); 61 Log.d(TGA, "onpause"); 62 } 63 64 protected void onStop() { 65 super.onStop(); 66 Log.d(TGA, "onStop"); 67 } 68 69 protected void OnDestroy() { 70 super.onDestroy(); 71 Log.d(TGA, "onDestroy"); 72 } 73 74 protected void onRestart() { 75 super.onRestart(); 76 Log.d(TGA, "onRestart"); 77 } 78 }
在onCreate()方法中,分别为两个按钮注册了点击事件,点击第一个按钮会启动NormalActivity,点击第二个按钮会启动DialogActivity。然后在Activity的七个回调方法中分别打印一句话,在通过日志
来理解活动的生命周期。
运行程序,效果下图如图所示:
观察LogCat中的打印日志,可以得到下图所示:
通过日志可以看到,当MainActivity第一次被创建时会依次执行onCreate()、onStart()、onResume()方法。
点击一个按钮,启动NormalActivity,得到下图所示:
此时查看LogCat打印的日志可以得到下图:
由于NormalActivity把MainActivity完全挡住,所以onPause()和onStop()方法都会被执行。然后按Back键返回到MainActivity,LogCat打印的日志信息如下图所示:
由于MianActivity之前已经进入停止状态,所以onRestart()方法会被执行,之后由依次onStart()和onResume()方法。
然后在点击第二个按钮,启动DialogActivity,如下图所示:
此时观察LogCat的打印信息,会得到如下图所示的信息:
由于DialogActivity没有完全挡住MainActivity,此时MainActivity只是进入了暂停状态,只有onPause()方法会被执行。
相应地,按下Back键返回MainActivity也只有onResume()方法会被执行。如下图所示:
最后在MainActivity界面下按下Back键退出程序,查看LogCat的打印信息,会得到下图所示:
一次执行了onPause()和onStop()方法。程序并没有执行onDestroy()方法,根据官方给出的活动的生命周期图,可以看到app process killed可以摧毁程序的进程。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。