Android四大组件之Activity

来源:互联网 发布:考试通软件 编辑:程序博客网 时间:2024/06/04 23:34

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的基本学习,欢迎大家留言交流。

1 0
原创粉丝点击