浅谈Android中Activity的生命周期和加载模式

原创 2015年11月17日 17:32:26

我们在面试Android工程师的过程中经常会被问到这么一些问题,例如:Activity的生命周期,Activity的加载模式,Android中的四大组件,以及Object类的几大方法这么一些基础的问题,那么我们今天就就Activity的声明周期来探讨探讨!!!

借调书上的一句话:

当Activity处于Android应用中运行时,它的活动状态由Android以Activity栈的形式管理.当前活动的Activity位于栈顶.随着不同应用的运行,每个Activity都有可能从活动状态转入非活动状态,也可能从非活动状态转入活动状态.这段话大致描述了Activity的工作形式.那么下来我们就从细节入手仔细谈谈Activity.

Activity在Android中的活动状态大致有以下4种:

1.活动状态:当前Activity位于前台,用户可见,可以获得焦点.(就是你平常使用应用时点击的那个界面)


2.暂停状态:其他Activity位于前台,该Activity依然可见,只是不能获得焦点.(例如,当一个半透明的activity打开时(如一个对话框),以前的activity就暂停了。只要 activity仍然是部分可见,但目前没有获得焦点,它就依然处于暂停状态。)


3.停止状态:该Activity不可见,失去焦点.(当从Activity.A跳转到Activity.B时Activity.A处于停止状态)


4.销毁状态:该Activity结束,或Activity所在的虚拟机进程被结束.(即就是Activity.finish())


下面我们给一张图来看看Activity的运行过程:


在Activity声明周期中的,如下方法会被系统回调:

onCreate(Bundle savedStatus):创建Activity时被回调.该方法只会被调用一次.

在onCreate()方法中对当前Activity执行初始化.


onStart():启动Activity时被回调.

此时activity用户可见,包括有一个activity在他上面,但没有将它完全覆盖,用户可以看到部分activity但不能与它交互


onRestart():重新启动Activity时被回调.

基本没什么用,就是设置了一下当前的使用状态.


onPause():暂停Activity时被回调.

当你的activity进入暂停状态,系统将对你的Activity调用 onPause()方法。在此方法中,你可以停止那些在暂停状态时不应该继续进行的行为(如视频播放),或者保存一些需要永久保存的信息。 如果用户返回到你的activity,系统将从暂停状态中恢复它,并调用onResume()方法,在onResume方法中恢复这些信息。

一个暂停状态的Activity依然保持活力(保持所有的状态,成员信息,和窗口管理器保持连接),但是在系统内存极端低下的时候将被杀掉。


onResume():恢复Activity时被回调,onStart()方法后一定会回调onResume()方法.

此时activity获得用户焦点,在与用户交互.


onStop():停止Activity时被回调.

当系统内存需要被用在其他地方的时候,Stopped的Activity将被杀掉。


onDestroy():销毁Activity时被回调,该方法只会被调用一次.

在onDestory()释放所有的资源。


注意:

如果一个Activity是Paused或者Stopped状态,系统可以将该Activity从内存中删除,Android系统采用两种方式进行删除,要么要求该Activity结束,要么直接杀掉它的进程。当该Activity再次显示给用户时,它必须重新开始和重置前面的状态。


下面我们来一段代码测试一下:(界面中只有两个按钮,Xml文件此处省略)view plaincopy

package org.crazyit.app;  
  
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.widget.Button;  
  
public class Lifecycle extends Activity {  
    final String TAG = "--CrazyIt--";  
    Button finish, startActivity;  
  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
        // 输出日志  
        Log.d(TAG, "-------onCreate------");  
        finish = (Button) findViewById(R.id.finish);  
        startActivity = (Button) findViewById(R.id.startActivity);  
        // 为startActivity按钮绑定事件监听器  
        startActivity.setOnClickListener(new OnClickListener() {  
            @Override  
            public void onClick(View source) {  
                Intent intent = new Intent(Lifecycle.this, SecondActivity.class);  
                startActivity(intent);  
            }  
        });  
        // 为finish按钮绑定事件监听器  
        finish.setOnClickListener(new OnClickListener() {  
            @Override  
            public void onClick(View source) {  
                // 结束该Activity  
                Lifecycle.this.finish();  
            }  
        });  
    }  
  
    @Override  
    public void onStart() {  
        super.onStart();  
        // 输出日志  
        Log.d(TAG, "-------onStart------");  
    }  
  
    @Override  
    public void onRestart() {  
        super.onRestart();  
        // 输出日志  
        Log.d(TAG, "-------onRestart------");  
    }  
  
    @Override  
    public void onResume() {  
        super.onResume();  
        // 输出日志  
        Log.d(TAG, "-------onResume------");  
    }  
  
    @Override  
    public void onPause() {  
        super.onPause();  
        // 输出日志  
        Log.d(TAG, "-------onPause------");  
    }  
  
    @Override  
    public void onStop() {  
        super.onStop();  
        // 输出日志  
        Log.d(TAG, "-------onStop------");  
    }  
  
    @Override  
    public void onDestroy() {  
        super.onDestroy();  
        // 输出日志  
        Log.d(TAG, "-------onDestroy------");  
    }  
}  



第二个Activity:

package org.crazyit.app;  
  
import android.app.Activity;  
import android.os.Bundle;  
import android.widget.TextView;  
  
public class SecondActivity extends Activity {  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        TextView tv = new TextView(this);  
        tv.setText("对话框风格的Activity");  
        setContentView(tv);  
    }  
}  




  

首先打开APP显示如下log;


点击"启动对话框风格的Activity"后:


点击手机的返回键后:


点击手机home键后:


在手机上再次启动该应用程序:


点击程序界面上的"退出"按钮后:


通过上面的运行,相信大家对Activity的声明周期和Activity在不同状态间的切换时所回调的方法有了更深层次的理解.

下面我们再来聊聊Activity的四种启动方式:

Activity在AndroidManifest.xml文件中的配置信息有一个android:launchMode属性,该属性就是用来配置该Activity的加载模式的下面我们来具体介绍:

Activity有四种加载模式分别如下:

1.standard:标准模式,这是默认的加载模式.

2.singleTop:Task(Activity栈)顶单例模式.

3.singleTask:Task内单例模式.

4.singleInstance:全局单例模式.

这四个分别是Activity的加载模式,在Android中使用Task来管理多个Activity,当我们启动一个应用时,Android就会为它创建一个Task,然后启动这个应用的入口Activity即就是属性为

[html] view plaincopy
  1. <intent-filter>  
  2.     <action android:name="android.intent.action.MAIN" />  
  3.     <category android:name="android.intent.category.LAUNCHER" />  
  4. </intent-filter>  
的Activity.


standard模式:


上图显示了standard模式的启动过程:standard模式会不断启动新的Activity,当启动自身时他仍会启动新的Activity.且所有Activity都在一个Task内.


singleTop模式:


上图显示了singleTop模式的启动过程:这种模式与standard模式大致相同,只是当将要被启动的目标Activity位于Task栈顶时,系统不会创建新的目标Activity的实例,而是直接复用已有的Activity实例.

此种加载模式只有当要加载的Activity已经位于栈顶时它才会复用已有的Activity,所以叫Task顶单例模式.


singleTask模式:


上图显示了singleTask模式的启动过程:

如果将要启动的目标Activity不存在,系统将创建目标Activity实例并且将其放置与栈顶,

如果将要启动的目标Activity已经位于Task栈顶时,此时系统不会创建新的目标Activity的实例,而是直接复用已有的Activity实例.与singleTop模式相同,

如果将要启动的目标Activity已经存在,但没有位于栈顶,系统将把位于该Activity上面的所有Activity移出Task栈,使得目标Activity重新位于栈顶.

在一个Task栈中同类型的Activity只会保留一个所以叫Task内单例模式.


singleInstance模式


上图显示了singleInstance模式的启动过程:

如果将要启动的目标Activity不存在,系统将会先创建一个全新的Task,再创建目标Activity的实例,并将它加入到新的Task的栈顶.

如果将要启动的目标Activity已经存在,无论它位于哪个应用程序中,不论它位于哪个Task中,系统将会把该Activity所在的Task转到前台,从而该Activity显示.

这种加载模式无论从哪个Task中启动目标Activity,都只会创建一个目标Activity实例,并且使用一个新的Task栈来装载它,这就是全局单例模式.

在最后我们再来举个例子介绍一下这个Activity中如何配置加载模式:

既然是给Activity配置信息那么必定实在AndroidManifest.xml中进行配置;

<span style="font-size:14px;"><activity
            android:name="com.xiyou.OtherActivity"
            android:label="@string/OtherName" 
            android:launchMode="standard">
            
</activity></span>

如有错误.敬请指出.

版权声明:本文为博主原创文章,未经博主允许当然可以转载,程序猿要有开源的意识,追求清新脱俗的代码。

Activity的生命周期和启动模式详解

BACK键:   当我们按BACK键时,我们这个应用程序将结束,这时候我们将先后调用onPause()->onStop()->onDestory()三个方法。 再次启动App时,会执行onCreate...
  • robertcpp
  • robertcpp
  • 2016年07月01日 10:12
  • 5080

Activity的生命周期(三)——结合Activity的生命周期理解子类继承父类预加载数据

父类代码: /** * @author 贾涛 * @date 2016-2-27 上午5:59:49 */ public class BaseActivity extends Ac...
  • lvyoujt
  • lvyoujt
  • 2016年02月27日 07:52
  • 315

Android Activity生命周期都该做哪些事情?

Android系统根据生命周期的不同阶段唤起对应的回调函数来执行代码。系统存在启动与销毁一个activity的一套有序的回调函数。本节来讨论下不同生命周期的回调函数里都该做哪些事情,不该做哪些事情。理...
  • feidu804677682
  • feidu804677682
  • 2015年05月25日 16:30
  • 6328

android4.0 屏幕切换(避免重走Activity的生命周期)

2012-09-13 16:33 1221人阅读 评论(2) 收藏 举报   最近在学习基于android4.0新增加的新特性ActionBar和Fragment的开发,在android4.0 ...
  • dj0379
  • dj0379
  • 2014年10月24日 10:03
  • 589

Activity生命周期以及launchMode对生命周期的影响

本文主要描述一下Activty的生命周期,以及launchMode对生命周期的影响,onNewIntent,onSaveInstanceState,onRestoreInstanceState方法何时...
  • songshizhuyuan
  • songshizhuyuan
  • 2015年07月29日 17:17
  • 1319

Activity入门--“生命周期”,启动模式,Intent跳转Flag方式

掌握生命周期对开发者来说很基础,但至关重要,当理解好了生命周期,才可以写出连贯流畅的程序,并且能掌握如何管理应用程序的资源,得到更好的用户体验。 什么是Activity(活动)? 所谓活动就是吸引...
  • w372426096
  • w372426096
  • 2016年09月08日 14:45
  • 749

Android动态加载进阶 代理Activity模式

基本信息 作者:kaedea 项目:android-dynamical-loading 技术背景 简单模式中,使用ClassLoader加载外部的Dex或Apk...
  • hjh200507609
  • hjh200507609
  • 2016年01月20日 16:56
  • 1334

Activity的生命周期函数、onActivityResult、intent和启动模式的调用关系

将activity的启动模式和intent传值问题进行了总结和思考
  • cbzcbzcbzcbz
  • cbzcbzcbzcbz
  • 2017年07月25日 11:14
  • 384

Android之Activity生命周期浅析(一)

Activity作为四大组件之一,出现的频率相当高,基本上我们在android的各个地方都能看见它的踪影,因此深入了解Activity,对于开发高质量应用程序是很有帮助的。今天我们就来详细地聊聊Act...
  • javazejian
  • javazejian
  • 2016年07月17日 15:31
  • 25395

Android重启当前Activity以及Activity生命周期的变化

重启Activity的方法private void reStartActivity() { Intent intent = getIntent(); finish(); sta...
  • liuweiballack
  • liuweiballack
  • 2015年08月06日 11:34
  • 5011
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:浅谈Android中Activity的生命周期和加载模式
举报原因:
原因补充:

(最多只允许输入30个字)