本篇隨筆將會深入學習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的生命周期函數調用時機后,就可以靈活的在對應的方法中來完成我們需要完成的功能了。