Android 組件系列-----Activity生命周期


本篇隨筆將會深入學習Activity,包括如何定義多個Activity,並設置為默認的Activity、如何從一個Activity跳轉到另一個Activity,還有就是詳細分析Activity的生命周期函數。

一、如何定義多個Activity

在我們之前寫的程序當中,我們都是用的MainActivity這個由ADT自動生成的Activity,但是我們一個程序可能有多個Activity,那么我們應該如何定義多個Activity呢?步驟如下:

1.定義一個類讓其繼承Activity這個父類

2.重寫父類的onCreate()方法

3.在AndroidManifest.xml文件中注冊這個Activity

首先我們再寫一個布局文件second.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/firstTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="FirstActivity" />

    <Button 
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_below="@id/firstTextView"
        android:text="SecondActivity"/>
    
</RelativeLayout>

接着寫一個類SecondActivity,繼承Activity這個類,並重寫onCreate()方法

package com.xiaoluo.android_multiactivity;

import android.app.Activity;
import android.os.Bundle;

public class SecondActivity extends Activity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second);
    }
}

最后在我們的AndroidManifest.xml文件中對這個Activity進行注冊

    <activity 
            android:name="com.xiaoluo.android_multiactivity.SecondActivity"
            android:label="SecondActivity">
       <!--如果加上了下面這個子元素,則表示該Activity是這個應用程序默認啟動的Activity--> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>

這樣,我們在啟動了我們的應用程序后,就會默認加載SeoncdActivity,然后加載我們的布局文件

二、如何從一個Activity跳轉到另一個Activity

我們在知道如何定義多個Activity后,接下來要了解的就是如何從一個Activity跳轉到另一個Activity上,就像我們web程序一樣,首先進入一個主頁,然后再通過按鈕或者鏈接跳轉到另外的頁面上。我們先來看看兩個布局文件

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/firstTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="FirstActivity" />

    <Button 
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_below="@id/firstTextView"
        android:text="SecondActivity"/>
    
</RelativeLayout>

second.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:id="@+id/secondTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="第二個Activity"/>

</LinearLayout>

我們希望通過點擊第一個Activity的Button按鈕跳轉到第二個Activity上

我們來看看MainActivity這個類該怎樣寫:

package com.xiaoluo.android_multiactivity;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity
{
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        button = (Button)findViewById(R.id.button);
        ButtonListener buttonListener = new ButtonListener();
        button.setOnClickListener(buttonListener);
    }
    
    class ButtonListener implements OnClickListener
    {
        @Override
        public void onClick(View v)
        {
            //    在android中,要做各種事,例如啟動一個Activity,都需要生成一個Intent(意圖)對象
            Intent intent = new Intent();
            /*
             * Context是一個類,所有的Activity都是Context的一個子類,所以
             * setClass方法的第一個參數接收的是一個Context類型對象,我們將當前這個Activity對象傳進去就可
             * 第二個參數就是我們需要啟動的Activity的class對象
             */
            intent.setClass(MainActivity.this, SecondActivity.class);
            startActivity(intent);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

啟動另一個Activity最重要的方法就是首先創建一個Intent對象,在Android中,我們幾乎要做的任何事,都是要通過Intent(意圖)對象來做的,然后通過setClass方法來設置我們要跳轉的Activity的類,最后調用startActivity方法來跳轉到我們的Activity上。

這樣當我們點擊了第一個Activity的Button按鈕后,就會跳轉到第二個Activity上。

三、Back Stack

這一節我們來稍微探討一下Android當中的Back Stack這個東西,back stack可稱為后退棧,里面存放的是我們的Activity對象,我們知道棧是一種后進先出的數據結構,當我們的應用程序啟動時,Android會自動創建我們默認的一個Activity對象,將其放在棧底,當我們從這個Activity跳轉到另一個Activity對象上時,此時就會生成第二個Activity的一個對象,然后將其放在back stack中,這樣第二個Activity對象就位於棧頂了,要記住:Android應用程序顯示的永遠都是棧頂的Activity。當來第三個Activity對象時,同樣將其放入back stack當中,此時第三個Activity就成為了棧頂對象,這樣我們看到的就是第三個Activity對象對應的布局文件,如果此時我們點擊返回按鈕,此時根據棧的"后進先出"原則,首先將棧頂的第三個Activity對象從back stack中彈出去,這時位於棧頂的就是第二個Activity對象,此時界面就是這個Activity對象的布局文件,再點擊返回,又將第二個Activity對象彈出去,此時就會顯示第一個Activity對象的布局文件,這就是為什么我們點擊返回后會跳到上層頁面的原因所在!

四、Activity的生命周期

最后一節,將來詳細探討一下Activity的生命周期,我們要了解在Activity對象從創建到最后被銷毀中間經歷了哪些階段,每個階段我們又能讓其為我們做什么?

Activity的生命周期分為7段,每個階段都有一個對應的生命周期函數,我們首先來看一張圖,來看看這七個生命周期函數所執行的時間

我們下面來通過一個例子來詳細的探討這7個生命周期函數調用的時機,同樣是從一個Activity調到另一個Activity,然后我們在每個函數里打印出對應的信息,來看看生命周期函數調用的時機:

首先來看看兩個布局文件,很簡單

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
    
    <Button 
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/textView1"
        android:text="跳轉到SecondActivity"/>
    
</RelativeLayout>
<?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="match_parent"
        android:layout_height="wrap_content"
        android:text="SecondActivity"/>
    
</LinearLayout>

接着來看看我們的兩個Activity類:

MainActivity:

public class MainActivity extends Activity
{
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        button = (Button)findViewById(R.id.button);
        ButtonListener buttonListener = new ButtonListener();
        button.setOnClickListener(buttonListener);
        
        System.out.println("MainActivity: onCreate");
    }
    
    class ButtonListener implements OnClickListener
    {
        @Override
        public void onClick(View v)
        {
            Intent intent = new Intent();
            intent.setClass(MainActivity.this, SecondActivity.class);
            startActivity(intent);
        }
    }
    
    @Override
    protected void onStart()
    {
        super.onStart();
        System.out.println("MainActivity: onStart");
    }
    
    @Override
    protected void onResume()
    {
        super.onResume();
        System.out.println("MainActivity: onResume");
    }
    
    @Override
    protected void onPause()
    {
        super.onPause();
        System.out.println("MainActivity: onPause");
    }

    @Override
    protected void onStop()
    {
        super.onStop();
        System.out.println("MainActivity: onStop");
    }
    
    @Override
    protected void onRestart()
    {
        super.onRestart();
        System.out.println("MainActivity: onRestart");
    }
    
    @Override
    protected void onDestroy()
    {
        super.onDestroy();
        System.out.println("MainActivity: onDestroy");
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

SecondActivity類:

public class SecondActivity extends Activity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second);
        System.out.println("SecondActivity: onCreate");
    }
    
    @Override
    protected void onStart()
    {
        super.onStart();
        System.out.println("SecondActivity: onStart");
    }
    
    @Override
    protected void onResume()
    {
        super.onResume();
        System.out.println("SecondActivity: onResume");
    }
    
    @Override
    protected void onPause()
    {
        super.onPause();
        System.out.println("SecondActivity: onPause");
    }

    @Override
    protected void onStop()
    {
        super.onStop();
        System.out.println("SecondActivity: onStop");
    }
    
    @Override
    protected void onRestart()
    {
        super.onRestart();
        System.out.println("SecondActivity: onRestart");
    }
    
    @Override
    protected void onDestroy()
    {
        super.onDestroy();
        System.out.println("SecondActivity: onDestroy");
    }
}

最后,要記住,在AndroidManifest.xml文件中對Activity進行注冊,並設置一個默認啟動的Activity,我們這里就是MainActivity:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.xiaoluo.android_lifecycle"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />

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

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <activity 
            android:name="com.xiaoluo.android_lifecycle.SecondActivity"
            android:label="SecondActivity">
        </activity>
    </application>

</manifest>

下面我們啟動我們的程序,然后點擊第一個Activity的Button按鈕跳轉到第二個Activity上,再點擊返回按鈕返回到第一個Activity上,我們來看看控制台的輸出,並解析其為什么會打印出這樣的語句,也就是為什么會在這個時候調用該周期函數:

首先會打印出這三條語句,因為我們默認啟動的是MainActivity對象,所以此時當Activity對象一啟動並顯示出能與用戶交互的界面時會分別調用 onCreate、onStart和onResume方法,此時我們點擊Button按鈕跳轉到第二個Activity上:

此時,根據上面我們的那張表格知道,當一個Activity准備跳轉到另一個Activity上時,當前這個Activity對象會調用onPause方法,此時跳轉到第二個Activity上時,會因此調用第二個Activity對象的onCreate、onStart和onResume方法,最后,因為第二個Activity的界面完全覆蓋了第一個Activity,所以此時會調用第一個Activity對象的 onStop 方法

這時我們點擊返回來回到第一個Activity頁面上:

我們看到,因為此時也是從一個Activity跳轉到另一個Activity,所以此時會調用第二個Activity對象的onPause方法,那么為什么此時會接着調用我們第一個Activity對象的onRestart方法呢?這時就要回顧下我們第三節的那個 back stack 知識點了,我們知道,當創建一個Activity對象后,會將其因此放入back stack棧中,Android顯示的總是棧頂的Activity對象,因為當前默認啟動的是MainActivity對象,所以MainActivity對象是放在最下面,SecondActivity對象放在棧頂上,當我們點擊返回時,會將SecondActivity對象從棧中彈出去,所以此時因為MainActivity對象是存在於stack棧中的,所以此時會調用其 onRestart 方法,而不是onCreate方法,緊接着就是調用 onStart、onResume方法,最后第一個Activity覆蓋了第二個Activity,所以分別又會調用SecondActivity對象的 onStop和 onDestroy方法,將SecondActivity對象銷毀。

這就是我們整個的Activity對象的生命周期函數的調用含義,我們來看看Android官方提供的Activity生命周期圖:

相信結合上述例子以及android官方提供的Activity生命周期圖,大家應該會對Activity對象的生命周期了如指掌了吧。

五、Activity對象的三種狀態

最后我們再來了解一個知識點--Activity對象的三種狀態:

①Resumed狀態:此時我們的Activity處於活動狀態,可以與用戶進行交互。

②Paused狀態:此時我們啟動了第二個Activity,但是第一個Activity對象並沒有消失掉,例如彈出式的對話框,此時就屬於Paused狀態。

③Stopped狀態:此時第二個Activity完全覆蓋了第一個Activity,這時第一個Activity對象就處於Stopped狀態。

 

總結:本篇隨筆講解了如何定義多個Activity,並學習了如何從一個Activity跳轉到另外的Activity上,最后還詳細講解了Activity的生命周期,我們在了解了Activity的生命周期函數調用時機后,就可以靈活的在對應的方法中來完成我們需要完成的功能了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM