Photo by Đức Trịnh on Unsplash
Activity 是 Android 很重要的一個組件,主要用在與使用者互動時的入口點或用戶界面,類似 VB 或 C# 開發工具的 Form,例如:使用 Line 與朋友聊天是一個 Activity,切換到主頁或貼圖下載時,則又是另一個 Activity,這時有人撥電話進來,顯示的電話接聽畫面又是另一個 Activity,如果應用程式有多個 Activity ,就需要將其中一個 Activity 標記為主要 Activity,也是用戶啟動應用程式時出現的第一個畫面。且在 Activity 中可以啟動另一個 Activity,以執行不同功能的操作。
[Activity生命週期]
如果曾寫過 C/C++ 程式語言的朋友,會知道一般程序是從 main()函數開始,而 Android 系統則經由 Activity 的 onCreate()方法開始進入程序。Activity 在應用程式的過程中,從開始到結束,甚至從記憶體中刪除,這些程序稱做「Activity生命週期」,這個生命週期的觀念與程式編寫有很大的關係,設計者必須在使用者操作到某種情境時(如建立、暫停等),執行特定的語法來與使用者互動,先從以下這張圖說起:Android 系統的 Activity 主要有 4 個狀態:活動狀態(Active/Running)、暫停狀態(Paused)、停止狀態(Stopped)及銷毀狀態(Dead/Inactive),如上圖彩色的橢圓形框,7 個方法:onCreate()、onStart()、onResume()、onPause()、onRestart()、onStop()及 onDestroy(),如上圖方形框。說明如下:
4種狀態 | 說明 |
---|---|
活動狀態(Active/Running) | 當 Activity 位於螢幕的最上面時的狀態,同一個時間只會有一個 Activity 處於活動(Active) 或運行(Running)狀態,其他 Activity 會處於 Dead、Stopped 或是 Paused 狀態。 |
暫停狀態(Paused) | 當 Activity 失去焦點的狀態,畫面仍然可見時,此時的狀態變成 Paused。此時的 Activity 只是失去與使用者互動的畫面,其所有的狀態及資訊都還存在。 |
停止狀態(Stopped) | 當 Activity 完全不可見時的狀態,但仍然保存所有的狀態和資訊。當記憶體低的情況下, 它將會被系統killed(殺死)。 |
銷毀狀態(Dead/Inactive) | 當 Activity 被系統回收掉時,此時就是處於 銷毀狀態,所佔用的記憶體回收。 |
在 Activity 狀態改變時,會呼叫不同的方法來因應,總計 7 個方法,如以下說明。
方法 | 說明 |
---|---|
onCreate | 當 Activity 被建立時候會自動執行 onCreate 方法來進行一些初始化動作,且只會執行一次。 |
onStart | 在 onCreate 或 onRestart 方法執行完成後,就由 onStart 接手繼續將 activity 的 UI 物件初始化與可視化, 當 Activity 在前臺顯示時,會執行 onResume。 |
onResume | onResume 的階段是應用程式持續處於執行中,且與使用者互動進行中,直到使用者的切換到其他 Activity 頁面, 或開啟其它應用程式,如接到其他人來電,這時就會進入 onPause 暫停的狀態。 |
onPause | 系統要執行另一個活動時,或原 Activity 可見但失去焦點時觸發。 |
onRestart | 將 Activity 從 onStop 狀態喚醒時會用 onRestart 方法,這個方法會比再次執行 onStart 好。執行完 onRestart 之後 執行 onStart。 |
onStop | 當這個 Activity 完全無法呈現在 UI 時,會呼叫 onStop 方法。有三種情況會呼叫 onStop()方法: (1) 一個新的 Activity 被執行, (2) 一個已經存在的 Activity 被切換到最前端。 (3) 這個 Activity 要被銷燬。 如果使用者要重新開始這個 Activity,則會呼叫 onRestart方法;若這個 Activity 要被銷毀,則呼叫 onDestroy 方法。 |
onDestroy | 當 Activity 銷毀前會呼叫 onDestroy 方法,如 Activity 呼叫了 finish() 方法來結束這個 Activity, 或因為系統為了節省空間而銷毀這個 Activity。 |
[建立 Activity]
建立 Activity 有兩個方法,一是在 Android Studio 建立,另一個是使用 java 程式建立,建立新的 Activity 之後,如要使用新建立的 Activity 有兩個方法,一是在啟動設定檔 AndroidManifest.xml 檔中,定義啟動時預設的 Activity,但這只能設定一個 Activity,無法由一個 Activity 去開啟另一個 Activity,這時需要 java/kotlin 來開啟其他的 Activity。另一個方法就是直接使用 java 指令來開啟 Activity。在 Android 應用程式中,若存在多個 Activity 時,可使用 startActivity() 方法來啟動其他的 Activity。startActivity()的語法格式如下:
public void startActivity (Intent intent)這裡使用 Intent 類別當作參數,Intent 是 Android 應用程式中在各組件間的通信方式。有關 Intent 物件的建立與應用,留待稍後的文章來瞭解。以下是建立 Activity 的步驟與方法:
方法一:使用 Android Studio 建立
Activity 放在 res\layout 目錄下,對著 layout 按右鍵 →「New」→「Activity」→ (選擇 Activity 的樣版),一般選擇「Empty Activity」,依自己的情況建立不同的模版。如下圖;
選擇模版後,出現以下視窗,輸入 Activity 名稱、Layout 名稱等,按下 Finish 就完成了。
方法二:使用 java 程式建立
(1) 建立的 Activity 一般是繼承自 android.app 套件中的 Activity 類別,或是繼承自 Activity 的子類別。如要建立一個名為 MyActivity 的 Activity,程式如下:
import android.app.Activity; public class MyActivity extends Activity { }
(2) 建立 Activity 後,通常需要重寫呼叫的方法,檔這些方法是文章上一段提到的 Acticity 生命週期的七個方法,一般都需要重寫 onCreate(),在這個階段打開佈局 Layout檔,並在這個方法中使用 setContentView() 來設定要顯示的頁面,這個頁面是一個佈局的 XML 名稱。例如,在步驟(1)中建立的 Activity 中,重寫 onCreate() 方法,並設定要顯示的頁面為 activity_my_layout.xml,程式碼如下:
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my_layout); }setContentView(R.layout.activity_main)方法是 android.app.Activity 類別提供的方法,用來設定 Activity 本身的畫面配置資源,在 Activity 中存取資料需透過「R」類別,R 類別代表應用程式內的資源。
[設定 Activity]
使用 Android Studio 建立新的 Activity 後,會自動在 AndroidManifest.xml 檔中建立這個 Activity 的設定。如果沒有在 AndroidManifest.xml 檔中設定 Activity 標記,而又在程式中啟動新的 Activity,將會出現異常資訊。設定 Activity 標記的方法是在<application>與</application>標記中間增加<activity>和</activity>標記,格式如下:<activity android:name="實現類" android:label="說明的文字" android:theme="要應用的主題" … > </activity>
[關閉 Activity]
在Android 中,如果要關閉目前的 Activity,只要使用 Activity 類別提供的 finish()方法即可。finish() 語法格式如下:public void finish()
[Activity應用情境]
以下幾種執行 Activity 啟動時、按下 Home 鍵及退回主畫面時,Actvity 呼叫方法的順序,如以下說明:(1) 啟動 Ativity
Activity啟動後,首先調用 onCreate 方法,然後是 onStart 方法,最後是 onResume 方法,進入運行狀態,此時 Activity 顯示在畫面。Activity 執行方法的過程:Activity 啟動 → onCreate() → onStart() → onResume()依次被呼叫。
(2) 當前 Activity 執行中,按 Home 鍵回到主畫面
在當前的 Activity 點擊 Home 回到主畫面,此時 onPause 方法和 onStop 方法被執行,也就是點擊 Home 鍵回到主畫面,Activity 執行方法的順序為:→ onPause() → onStop() 依次被呼叫。
(3) 當點擊 Home 鍵回到主畫面後,再次點擊 App 回到 Activity
重新再回到 Activity 時,調用了onRestart 方法,onStart 方法,onResume 方法。Activity 執行方法的順序為:→ onRestart() → onStart() → onResume() 依次被呼叫。
(4)在原有的 Activity 再開啟新的 Activity
原來的 Activity 呼叫了 onPause 方法和 onStop 方法。原 Activity 執行方法的順序為:→ onPause() → onStop(),跟點擊 home 鍵時的順序是一樣的。有點需要注意的是,如果新的 Activity 使用了透明主題,那麼當前 Activity 不會呼叫 onStop 方法。在新的 Activity 其呼叫的方法被觸發前,要等原 Activity 的 onPause 方法執行結束後才會被呼叫。
(5) 點擊 Back 鍵退回時
當點擊 Back 鍵退回時,相當於退出了當前 Activity,Activity 將被銷毀,退出當前 Activity 執行方法的順序為:→ onPause() → onStop() → onDestroy() 依次被呼叫。
[程式範例]
(1) 新建一個模組 Module,使用上述方法一建立一個新的 Activity,名為 DetailActivity。(2) 開啟 manifests 目錄,打開 AndroidManifest.xml,在新增的 DetailActivity 標記加上 label 名稱。如下圖:
(3) 進入 res/layout 目錄下點選佈局檔 activity_main.xml。將預設的內容刪除,建立 2 個 TextView 文字框顯示帳號/密碼,2 個編輯框,2 個按鍵,以下是完整 XML 的內容。
<?xml version="1.0" encoding="utf-8" ?> <LinearLayout 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:padding="8dp" android:orientation="vertical" > <TextView android:id="@+id/acc" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20sp" android:textSize="22sp" android:text="帳號: " /> <EditText android:id="@+id/acc" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10sp" android:textSize="22sp" android:text="請輸入帳號 " /> <TextView android:id="@+id/pwd" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20sp" android:textSize="22sp" android:text="密碼: " /> <EditText android:id="@+id/acc" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10sp" android:textSize="22sp" android:text="請輸入密碼 " /> <Button android:id="@+id/cfm" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30sp" android:textSize="22sp" android:text="確定" /> <Button android:id="@+id/forget" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10sp" android:textSize="22sp" android:text="忘記密碼" /> </LinearLayout>(4) 進入 java 目錄下,開啟 MainActivity.java 程式,用 findValueById 連結 Button 元件,設定 setOnClickListener 監聽器,在 onClick 的方法內新增 Intent 實例,再執行 startActivity 開啟 DeatailActivity。程式如下:
package com.example.app2; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity { private Button forget; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); forget = (Button) findViewById(R.id.forget); forget.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this,DetailActivity.class); startActivity(intent); } }); } }新增的是下圖紅框處:
執行的結果如下:
[參考資料]
- Developer:Activity 简介
- CSDN:Android之Activity生命週期淺析(一)
- 明日科技:Android 從入門到精通
張貼留言