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

我们在面试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 plain copy
 
  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>

如有错误.敬请指出.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值