Android项目(三)-- Activity生命周期演示

来源:互联网 发布:lolypop女装淘宝网 编辑:程序博客网 时间:2024/05/21 14:46

查看 Android API 我们可以发现 Activity 实际上是继承了ApplicationContext 类,并复写了它的七个方法。

注:由于笔误,有些地方将Second单词打成了Secend,所以大家看的时候知道Secend是Second就行了。(还是粗心了啊快哭了

public class Activity extends ApplicationContext {    protected void onCreate(Bundle savedInstanceState);    protected void onStart();        protected void onRestart();    protected void onResume();    protected void onPause();    protected void onStop();    protected void onDestroy();}

下面我们来创建一个项目演示一下,项目里有两个 Activity ,分别为 FirstActivity 和 SecendActivity ,每个Activity 都有一个按钮并且复写了上面提到的7个方法,点击按钮会切换到另一个Activity。

FirstActivity 代码:

import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;public class FirstActivity extends Activity {private String logMessagePrefix = "FirstActivity ------ ";@Overrideprotected void onCreate(Bundle savedInstanceState) {System.out.println(logMessagePrefix + "onCreate");super.onCreate(savedInstanceState);setContentView(R.layout.activity_first);Button firstButton = (Button)findViewById(R.id.myFirstButton);firstButton.setText(R.string.first_text_button);firstButton.setOnClickListener(new OnClickListener() {public void onClick(View v) {Intent intent = new Intent();intent.setClass(FirstActivity.this, SecendActivity.class);startActivity(intent);}});}@Overrideprotected void onStart() {// TODO Auto-generated method stubSystem.out.println(logMessagePrefix + "onStart");super.onStart();}@Overrideprotected void onPause() {// TODO Auto-generated method stubSystem.out.println(logMessagePrefix + "onPause");super.onPause();}@Overrideprotected void onRestart() {// TODO Auto-generated method stubSystem.out.println(logMessagePrefix + "onRestart");super.onRestart();}@Overrideprotected void onResume() {// TODO Auto-generated method stubSystem.out.println(logMessagePrefix + "onResume");super.onResume();}@Overrideprotected void onDestroy() {// TODO Auto-generated method stubSystem.out.println(logMessagePrefix + "onDestroy");super.onDestroy();}@Overrideprotected void onStop() {// TODO Auto-generated method stubSystem.out.println(logMessagePrefix + "onStop");super.onStop();}}

SecondActivity 代码:

import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;public class SecondActivity extends Activity{private String logMessagePrefix = "SecendActivity ------ ";@Overrideprotected void onCreate(Bundle savedInstanceState) {System.out.println(logMessagePrefix + "onCreate");super.onCreate(savedInstanceState);setContentView(R.layout.activity_secend);Button secendButton = (Button)findViewById(R.id.mySecendButton);secendButton.setText(R.string.secend_text_button);secendButton.setOnClickListener(new OnClickListener() {public void onClick(View v) {Intent intent = new Intent();intent.setClass(SecendActivity.this, FirstActivity.class);startActivity(intent);}});}@Overrideprotected void onStart() {// TODO Auto-generated method stubSystem.out.println(logMessagePrefix + "onStart");super.onStart();}@Overrideprotected void onPause() {// TODO Auto-generated method stubSystem.out.println(logMessagePrefix + "onPause");super.onPause();}@Overrideprotected void onRestart() {// TODO Auto-generated method stubSystem.out.println(logMessagePrefix + "onRestart");super.onRestart();}@Overrideprotected void onResume() {// TODO Auto-generated method stubSystem.out.println(logMessagePrefix + "onResume");super.onResume();}@Overrideprotected void onDestroy() {// TODO Auto-generated method stubSystem.out.println(logMessagePrefix + "onDestroy");super.onDestroy();}@Overrideprotected void onStop() {// TODO Auto-generated method stubSystem.out.println(logMessagePrefix + "onStop");super.onStop();}}

AndroidManifest.xml 文件代码:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.stacker.helloandroid"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="15" />   <application android:icon="@drawable/ic_launcher" android:label="@string/app_name"><activity android:name=".FirstActivity" android:label="@string/first_activity_name"><intent-filter>  <action android:name="android.intent.action.MAIN" />   <category android:name="android.intent.category.LAUNCHER" />     </intent-filter>   </activity>   <activity android:name=".SecendActivity"         android:label="@string/second_activity_name"         />  </application>   </manifest>
现在运行项目,可以看到下面结果


第一个Activity 启动完成,一共调用了三个方法:onCreate, onStart, onResume,其功能分别是创建、运行、获取屏幕焦点,这就是创建一个Activity 所要做的步骤。点击按钮进入第二个Activity




从结果中我们可以看到切换到第二 Activity 时SecendActivity 也会执行 onCreate,onStart,onResume。在SecendActivity 启动完成后,FirstActivity 会调用stop 方法,根据官方API介绍,此方法会在 Activity 对用户不可见(即被其他Activity完全遮挡住,如果不完全遮挡会是什么情况?)时会被调用。再让我们来点击返回键(注意不是点击“go back first button”按钮)




当点击返回按钮时,由于第一个Activity 没有销毁,只是暂时 stop 了并未销毁还存在内存中,所以FirstActivity 会调用onRestart 方法。而SecendActivity 会调用 onStop方法和 onDestroy方法。这个时候SecendActivity 就从内存中销毁了。

假如我们点击的不是菜单返回键而是“go back first button” 按钮,结果又是会不会是一样的呢?我们来看看测试结果


对比结果我们可以发现,点击“go back first button” 按钮后,会调用 onCreate 方法再创建一个FirstActivity 而不是调用onRestart 方法去重启FirstActivity 了。看到这里大家可能就有个疑惑了,从运行结果看FirstActivity 切换到SecendActivity 后只是暂停运行,并没有调用 onDestroy方法进行销毁。我们点击“go back first button” 按钮后,应该和点击菜单返回键一样会重启FirstActivity 才对啊,为什么会再创建呢? 下面就来解释一下原因。

Android内存运行时会有一个栈数据区,来管理每一个Activity ,创建的 Activity 都会被压入栈,无论什么时候处在栈顶的那个Activity 就是正在与用户交互的那个Activity 。

我们先考虑第一种情况:点击菜单返回键

先是创建了FirstActivity 并压入栈,点击“go in secend button”按钮,创建 第二个Activity 并压入栈,此时栈顶是第二个Activity ,这个时候点击返回菜单键,则处在栈顶的第二个Activity 弹出栈并销毁(运行结果中可看出 SecendActivity 最后调用了onDestroy方法),此时第一次压入栈的Activity(即FirstActivity )就处在栈顶了。 


第二种情况:点击“go back first activity”

和第一种情况一样,创建第一个Activity(FirstActivity)压入栈,点击“go in secend button” ,会创建第二个Activity (SecendActivity)压入栈,继续点击“go back first button”时,和第一种情况不一样的是SecendActivity 并没有弹出栈(从运行结果中也可以看出SecendActivity没有调用onDestroy方法),而是创建了第三个Activity(FirstActivity)并压入栈,这个时候处在栈顶的是FirstActivity。栈内现在有三个Activity。


第二种情况之所以会创建三个Activity 其实是由于startActivity方法有关,查看API此方法的描述有这样一句话Launch a new activity”,翻译过来就是“加载一个新的 activity”,我们查看代码可以发现两个Activity中的按钮监听器代码里都调用 startActivity 方法。现在大家明白为什么了吧。

firstButton.setOnClickListener(new OnClickListener() {public void onClick(View v) {Intent intent = new Intent();intent.setClass(FirstActivity.this, SecendActivity.class);startActivity(intent);}});
secondButton.setOnClickListener(new OnClickListener() {public void onClick(View v) {Intent intent = new Intent();intent.setClass(SecendActivity.this, FirstActivity.class);startActivity(intent);}});
现在我们总结一下,点击菜单返回键会让栈顶的 Activity 弹出栈,点击“go back first button”按钮会创建启动新的Activity并压入栈。

这个问题解释清楚后,我们来看看上面红色部分提到的Activitiy 不被完全遮挡的情况。

现在我们将SecondActivity改成弹出的小窗口,只需要在AndroidManifest.xml文件中加上

android:theme="@android:style/Theme.Dialog"
语句即可。

<activity android:name=".SecendActivity"         android:label="@string/second_activity_name"        android:theme="@android:style/Theme.Dialog"         />

当然SecondActivity 中按钮的监听器代码也需要改变,不能调用startActivity 方法。

secondButton.setOnClickListener(new OnClickListener() {public void onClick(View v) {finish();}});
运行界面


运行结果


运行结果可以看出SecondActivity 启动后,SecondActivity并未完全遮挡住FirstActivity,所以FirstActivity 并没有调用onStop方法,当点击按钮返回FirstActivity后,FirstActivity调用了onResume重新获取屏幕焦点,接着SecondActivity做了销毁处理,调用了onStop和onDestroy。

下面附上官方API中生命周期图和这7个方法的解释(虽然是英文文档,可是大家还是要仔细看不要抵触。想干好程序员看英文文档这道坎是必须要过的...)



原创粉丝点击