活动的生命周期

Android中的活动是可以重叠的,每启动一个新的活动,就会覆盖在原活动之上,然后点击Back键就会销毁最上面的活动。

Android是使用任务(Task)来管理活动的,一个任务就是一组存放在栈里的活动的集合,也被称为返回栈(Back Stack)。

每个活动在其生命周期中有三种状态:

1.运行状态

一个活动位于返回栈的栈顶时,这时活动就处于运行状态。

2.暂停状态

一个活动不再处于栈顶位置,但仍然可见,这时活动就进入了暂停状态。

3.停止状态

一个活动不再处于栈顶位置,并且完全不可见是时候,就进入了停止状态。

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中的代码:

 package com.gfeng.activitylifecycletest;

 import android.app.Activity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.Window;
 import android.widget.Button;

 public class MainActivity extends Activity {

     public static final String TGA = "MainActivity";

     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         Log.d(TGA, "onCreate");
         requestWindowFeature(Window.FEATURE_NO_TITLE);
         setContentView(R.layout.activity_main);
         Button startNormalActivity = (Button) findViewById(R.id.start_normal_activity);
         startNormalActivity.setOnClickListener(new OnClickListener() {

             @Override
             public void onClick(View v) {
                 //显示Intent方法的使用
                 Intent intent = new Intent(MainActivity.this,NormalActivity.class);
                 startActivity(intent);

             }
         });

         Button startDialogActivity = (Button) findViewById(R.id.start_dialog_activity);
         startDialogActivity.setOnClickListener(new OnClickListener() {

             @Override
             public void onClick(View v) {
                 //显示Intent方法的使用
                 Intent intent = new Intent(MainActivity.this,DialogActivity.class);
                 startActivity(intent);

             }
         });

     }

     protected void onStart() {
         super.onStart();
         Log.d(TGA, "onStart");
     }

     protected void onResume() {
         super.onResume();
         Log.d(TGA, "onResume");
     }

     protected void onPause() {
         super.onPause();
         Log.d(TGA, "onpause");
     }

     protected void onStop() {
         super.onStop();
         Log.d(TGA, "onStop");
     }

     protected void OnDestroy() {
         super.onDestroy();
         Log.d(TGA, "onDestroy");
     }

     protected void onRestart() {
         super.onRestart();
         Log.d(TGA, "onRestart");
     }
 }

在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可以摧毁程序的进程。

Android学习笔记(六)的更多相关文章

  1. android学习笔记六——Spinner

    注:参考http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0105/2264.html Spinner ==> Spinner ...

  2. android学习笔记六

    Android中Activity的Intent大全 Api Level 3: (SDK 1.5) android.intent.action.ALL_APPS android.intent.actio ...

  3. Android学习笔记六:六大布局

    六大界面布局方式包括: 线性布局(LinearLayout).帧布局(FrameLayout).表格布局(TableLayout).相对布局(RelativeLayout).绝对布局(Absolute ...

  4. 【转】 Pro Android学习笔记(七六):服务(1):local和remote

    文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ Android提供服务,服务是运行在后台的 ...

  5. 【转】 Pro Android学习笔记(六九):HTTP服务(3):HTTP POST MultiPart

    目录(?)[-] 建立测试环境 开发环境导入第三方JAR HTTP Post Multipart小例子 HTTP POST不仅可以通过键值对传递参数,还可以携带更为复杂的参数,例如文件.HTTP Po ...

  6. 【转】 Pro Android学习笔记(六七):HTTP服务(1):HTTP GET

    目录(?)[-] HTTP GET小例子 简单小例子 出现异常NetworkOnMainThreadException 通过StrictMode进行处理 URL带键值对 Andriod应用可利用ser ...

  7. 【转】 Pro Android学习笔记(五六):配置变化

    目录(?)[-] Activity的destorycreate过程 Fragment的destorycreate过程 onSaveInstanceState saveFragmentInstanceS ...

  8. android学习笔记12——ListView、ListActivity

    ListView.ListActivity ==> ListView以垂直列表的形式显示所有列表项. 创建ListView的方式: 1.直接使用ListView创建 2.Activity继承Li ...

  9. 【转】 Pro Android学习笔记(八二):了解Package(1):包和进程

    文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ 在之前,我们已经学习了如何签发apk,见P ...

  10. 【转】Pro Android学习笔记(二三):用户界面和控制(11):其他控件

    目录(?)[-] Chronometer计时器控件 倒计时CountDownTimer Switch控件 Space控件 其他控件 Android提供了很多控件,基本上都是view的扩展. Chron ...

随机推荐

  1. mysql 配置 utf8 依然乱码

    mysql 乱码问题排除方案: 1.检查数据库及数据表是不是utf8字符集 2.查看一下jdbc.properties配置的数据库url 是否配置了characterEncoding=UTF-8或者在 ...

  2. iOS开发UI篇—使用嵌套模型完成的一个简单汽车图标展示程序

    iOS开发UI篇—使用嵌套模型完成的一个简单汽车图标展示程序 一.plist文件和项目结构图 说明:这是一个嵌套模型的示例 二.代码示例: YYcarsgroup.h文件代码: // // YYcar ...

  3. hdoj 4323

    题意:给你n个数,m个查询,查询中包括一个数和一个最大编辑距离d,问n个数中和这个数的编辑距离不超过d的有多少个 编辑距离:http://baike.baidu.com/view/2020247.ht ...

  4. Hibernate 映射关系

    映射组成关系 •建立域模型和关系数据模型有着不同的出发点: –域模型: 由程序代码组成, 通过细化持久化类的的粒度可提高代码的可重用性, 简化编程 –在没有数据冗余的情况下, 应该尽可能减少表的数目, ...

  5. Topcoder SRM 583 DIV2 SwappingDigits

    题目题意是交换一次,使数字最小,且数字前面不能有前导0 string minNumber(string num) { string res = num; for(int i = 0 ; i < ...

  6. Linux定时器相关源码分析

    Linux的定时器使用时间轮算法.数据结构不难理解,核心数据结构与散列表及其相似,甚至可以说,就是散列表.事实上,理解其散列表的本质,有助于对相关操作的理解. 数据结构 这里先列出一些宏,稍后解释: ...

  7. 如何利用Cloudera Manager来手动安装parcel包

    1.问题的描述: 当你利用Cloudera Manager部署了CDH的集群后,也许随着你的业务需求,你需要对你的就去哪做一些优化,或者扩展之类的,这个时候你可能需要下载安装一些组件.例如,我最近在阅 ...

  8. CSS 选择器【详解】

    转自:http://www.cnblogs.com/polk6/archive/2013/07/19/3142142.html CSS 选择器及各样式引用方式介绍 一个好的界面,是一个Web吸引人们最 ...

  9. swiper中提供的动画效果

    目前就只有这些,大家也可以尝试自己写一些想要的效果.动手试试,才能清楚每个效果具体是怎么回事~ bounce:弹跳两下出来flash:闪烁两下pulse:脉冲形式出来rubberBand:橡皮圈形式弹 ...

  10. java中时间类型的问题

    时间类型:System.currentTimeMillis() 获得的是自1970-1-01 00:00:00.000 到当前时刻的时间距离,类型为longimport java.sql.Date d ...