Android四大组件之Activity

Android四大组件之Activity

一、Activity的生命周期

Activity是Android的四大组件之一,可以说是android四大组件中最重要的组件之一。它负责了我们的界面显示,实际开发中我们通过setContentView(R.layout.id)设置界面显示的视图。在Android的项目结构设计中,Activity就相当于MVC设计模式中的View层。在Android的四大组件设计中,为了方便开发者进行开发使用,Android的开发者对四大组件通过生命周期进行管理,我们只需要继承Activity进行重写这些生命周期来管理和合理使用Activity。 
下面我们来一起看看Android官方文档上提供的Activity的生命周期图: 
life

通过这张图发现,Activity生命周期的主线是:onCreate()——>onStart()——>onResume()——>onPause()——>onStop()——>onDestroy()这六个流程主线。下面来分析下这六个生命周期的方法。 
1、创建Activity 
为了创建一个activity,我们必须创建一个Activity的子类,在我们的自定义子类中,我们需要实现这些回调方法,例如activity的create、stop、resume、destroy。方法的简介:

  • onCreate()方法
    这个方法我们必须实现,当我们创建一个activity的时候,系统会调用这个方法。重要的是,我们必须通过setContentView()来设定activity的显示视图。(不可见)
  • onStart()方法
    在我们创建了视图之后调用,在向用户展示之前调用。然后调用onResume方法。(不可见)
  • onResume()方法: 
    onResume方法是activity进行可见状态,能够与用户进行交互。(可见可用)
  • onPause()方法
    当我们离开这个activity时候系统调用这个方法。注意:它不意味着activity被销毁(destroy)。暂停状态,记得小时候打游戏,按暂停,游戏界面就会停止不动,属于可见状态,但是不能用,其实原理基本类似。(可见但不可用)
  • onStop()方法
    停止状态,当一个activity被另一个activity完全覆盖的时候,它仍然保留着信息,但是已经对用户不可见。(不可见)
  • onDestroy()方法
    此时activity已经被销毁,activity至此生命周期完全结束。(销毁)

通过上面的流程分析,从与用户交互的角度来说,Activity的状态分为不可见、可见可用、可见不可用、销毁。从android官方提供的文档来看,生命周期的三个阶段:

  • 完整生命周期(entire life)
    activity的完整生命周期从onCreate()方法到onDestroy()方法。在开发中我们在onCreate方法中进行一些一些初始化的操作,比如控件的初始化和设置控件的监听操作。例如:如果我们有个线程在后台下载数据,它可能在onCreate()方法中创建,在onDestroy()方法中进行销毁。

  • 可视生命周期(visible life)
    可视化的生命周期从onStart()方法到onStop()方法,这段生命周期内,用户可以在屏幕上看到此activity。例如:当一个新的activity启动了,这个activity就不在显示了。在这段生命周期内,你可以管控你需要向用户展示的资源。例如:你可以在onStart()方法中注册广播接受者(BroadcastReceiver),在onStop()方法中取消注册这个广播。

  • 前台生命周期(foreground life)
    前台生命周期,此段生命周期用户可以看见交互。这段生命周期从onResume()方法到onPause()方法。在这段生命周期内,这个activity在所有的activities的前面。当这个设备进入到休眠状态或当一个对话框出现的时候调用onPause()方法。由于在这之间的生命周期切换非常频繁,所以在这段生命周期内处理的逻辑处理代码要轻量级,避免来回切换让用户等待时间太久。

在实际的开发中,我们根据activity的生命周期来实现我们的逻辑处理。通常在开发中,在onCreate()方法中进行一些变量的初始化工作,包括变量的初始化、控件的初始化、控件设置监听等。当一个activity由于失去焦点时再次重新获取焦点调用onResume方法。在onResume()方法中我们可以处理一些比如界面的更新操作。

下面我们通过实例来验证:

public class MainActivity extends Activity {
    private static final String TAG = "ActivityLife";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d(TAG,"onCreate");
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d(TAG, "onStart");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG, "onStop");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "onResume");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "onPause");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy");
    }
}

(1)、启动activity,查看日志文件:
09-01 14:32:05.850 ﹕ onCreate
09-01 14:32:05.850 ﹕ onStart
09-01 14:32:05.850 ﹕ onResume
通过上面的方法分析,我们启动activity,activity获取焦点展现在我们的面前。
(2)、通过按钮进行activity的跳转,但是没有finish():
09-01 15:03:59.590 ﹕ onCreate
09-01 15:03:59.590 ﹕ onStart
09-01 15:03:59.590 ﹕ onResume
09-01 15:04:23.546 ﹕ onPause
09-01 15:04:23.550 ﹕ SecondActivity:onCreate
09-01 15:04:23.550 ﹕ SecondActivity:onStart
09-01 15:04:23.550 ﹕ SecondActivity:onResume
09-01 15:04:24.130 ﹕ onStop
通过分析发现,我们的mainActivity在SecondActivity界面获取到焦点后执行的onStop()方法。界面失去焦点后,OnPause()方法后。当我们执行finish方法后,就会在onStop方法执行后执行onDesdroy方法。
(3)、按Home键,执行顺序
09-01 15:15:04.262 ﹕ onPause
09-01 15:15:04.942 ﹕ onStop
(4)、横竖屏切换,相当于activity进行重新创建。所以声明周期会走正常创建的流程,一般在实际开发中,我们通过设定android:screenOrientation属性来设置是否允许横竖屏切换。

二、Activity的使用

1、首先在manifest配置文件中进行声明:在application节点下添加activity节点配置。

<manifest ... >
 <application ... >
    <activity android:name=".ExampleActivity" />
    ...
 </application ... >
 ...
</manifest >

activity子节点下面有很多属性配置这个activity,这么多属性中只有android:name是唯一必须要设置的,它确定了我们的activity是哪个类。所以一旦应用发布了,就不要去改变这个名称,不然会引起一起应用bug。更多的属性配置参照我的这篇博客
2、使用intent filter
通过使用intent-filter可以声明这个组件的工作方法。我们知道,当我们创建一个应用的时候,系统会自动给我们创建好一个主activity的配置。如下:

<activity android:name=".ExampleActivity" android:icon="@drawable/app_icon">
<intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

在这段配置中,我们发现节点配置的main,说明这是我们应用程序的入口。的属性值为LAUNCHER标识这是应用程序的启动界面。如果你打算你的应用只供自身调用不允许别的应用程序使用,你不需要设置更多的activity,只要设置一个activity拥有main的动作和Launcher的分类就可以。然后,如果你希望你的activity能够响应不同应用发送的intent,你必须为你的activity定义额外的intent-filter项。例如:为你所有响应的各项,你必须包含一个,并设置它的和元素或者元素节点,这些元素识别intent的类型并响应。

三、Activity的启动

在android系统中,我们通过Intent(意图)进行数据的传递或进行activity的跳转。在android系统中存在两种启动方式。 
1、显示启动
何为显示启动,就是在创建Intent的时指定要启动的activity的类。所以前提是我们已经知道Activity的类名称,这就运用在我们在开发app中进行activity的跳转。

Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivity(intent);

2、隐式启动
android系统给我们提供了许多服务,如打电话、发短信。但是在我们的应用中我们不知道具体的activity类名称,此时我们就需要用到隐式的activity启动方法。

//打电话
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:555-2368"));
startActivity(intent);

//发短信
Intent intent=new Intent();
intent.setAction("android.intent.action.SEND");
intent.setData(Uri.parse("mms:110"));
intent.addCategory(Intent.CATEGORY_DEFAULT);
startActivity(intent);

//打开网页
Intent intent=new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);

四、Activity的启动模式

android系统中对activity的启动模式设立了四种启动模式,分别是:standard、singleTop、singleTask、singleInstance这四种启动模式。在学习activity的启动模式之前,我们先了解下android中的任务栈的概念。如果我们有一定数据结构基础,说到‘栈’就知道它的特点:先进后出。知道这些后,我们在说android中是如何安排众多activity——通过任务栈来‘装’activity。如下图: 
task

通过这张图,我们可以看到android系统将activity按照先后顺序放入栈中进行管理。当我们点击返回键或执行finish方法就是从栈中退出activity。
在实际开发中,我们经常会遇到这种情况,我们从activity1——>activity2,然后执行完activity2——>activity1这种循环跳转,我们就会有这种疑惑,这里的activity1连续使用,系统是重新创建的activity1的实例还是复用已经创建存在的实例呢?这里就涉及到我们的activity的启动模式涉及。下面我们详细说说这四种启动模式:

  • standard(默认的模式)
    在创建一个activity的时候,系统默认的启动模式。在这种启动模式下,每次启动一个activity就创建一个实例放到任务栈中。所以我们对于activity不执行finish方法,就会存在多个activity的实例。
  • singleTop(单栈顶模式)
    如果一个activity实例已经存在当前任务栈的顶部,系统通过onNewIntent方法将intent发送到这个实例,而不是创建一个新的实例。
  • singleTask(单任务模式)
    如果一个activity已经在任务栈中存在,我们再次启动该activity就不需要重新创建实例。系统会将该activity实例上面的activity实例执行出栈操作,将此activity推至栈顶。
  • singleInstance(单例模式)
    如果应用1的任务栈中创建了MainActivity实例,如果应用2也要激活MainActivity,则不需要创建,两应用共享该Activity实例;

说完了基本概念,我们通过简单的实例验证下: 
我使用两个activity,使他们之间相互跳转。先来看下代码。
MainActivity代码:

 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    btn_go = (Button)findViewById(R.id.btn_go);
    btn_go.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(MainActivity.this,SecondActivity.class);
            startActivity(intent);
        }
    });
}

SecondActivity代码:

    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.secondlayout);
    Button btn_goMain = (Button)findViewById(R.id.btn_goMain);
    btn_goMain.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(SecondActivity.this,MainActivity.class);
            startActivity(intent);
        }
    });
}

(1)、将两个activity的启动模式设置为standard模式。通过android:launchMode进行设置 
,如下:

 <application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:launchMode="standard">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".SecondActivity"
        android:launchMode="standard"/>
</application>

我们先构造几个activity的实例,放到任务栈中。操作顺序: 
MainActivity->SecondActivity->MainActivity。 
我们通过截图看看我们按几次返回键退出应用:

!standard模式

通过截图我们看以看到,我们点击了多次才退出应用,这说明我们在跳转的过程中新建了多个activity的实例。 
standard

(2)singleTop模式, 
这种模式下,比如我们栈中有A->B->C->D,此时D在栈的顶部,我们再次进入D,如果采用standard模式,则栈中就有A->B->C->D->D,singleTop模式下就不会重新创建新的实例。A->B->C->D 
我们将SecondActivity设置为singleTop模式,查看运行截图: 
这里写图片描述

(3)singleTask模式: 
直接上运行截图,我们设置MainActivity为singleTask,我们点击退出,直接退出应用。 
这里写图片描述


以上就是关于Activity的基本学习,欢迎大家留言交流。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值