首先介紹下Activity
1.什麼是Activity:
Activity 是使用者介面程序,原則上它會提供給使用者一個互動的介面功能。它是 android 應用程式的基本功能單元。 Activity 本身是沒有介面的。所以activity類別創建了一個窗口,開發人員可以透過setContentView(View)介面把UI放到activity創建的窗口上,當activity指向全螢幕窗口時,也可以用其他方式實現:作為漂浮窗口(透過windowIsFloating的主題集合),或嵌入其他的activity(使用ActivityGroup)。 activity是單獨的,用於處理使用者操作。幾乎所有的activity都要和使用者打交道
2.Activity的生命週期
public class Activity extends ApplicationContext { protected void onCreate(Bundle savedInstanceState); protected void onStart(); protected void onRestart(); protected void onResume(); protected void onPause(); protected void onStop(); protected void onDestroy(); }
由圖可知:
在一個Activity Start onReate> onReumed ;在Activity被kill掉的時候方法順序是onPause -> onStop -> onDestroy,此為一個完整的Lifecycle。那麼對於中斷處理(例如電話來了),則是onPause -> onStop,恢復時onStart -> onResume;如果當前應用程式的是一個Theme為Translucent(半透明) 或者Dialog 的Activity那麼中斷就是onPause ,恢復的時候onResume。
那麼對於”Other app need memory”,就是我們手機在運行一個應用程序的時候,有可能打進來電話發進來短信,或者沒有電了,這時候程序都會被中斷,優先去服務電話的基本功能,另外系統也不允許你佔用太多資源,至少要保證一些功能(比如電話),所以資源不足的時候也就有可能被kill掉。
onCreate:在這裡建立介面,做一些資料的初始化工作; onStart: 到這一步驟變成「使用者可見可互動」的狀態;onResume:變成和用戶可交互的,(在Activity棧系統通過棧的方式管理這些Activity,即當前Activity在棧的最上端,運行完彈出棧,則回到上一個Activity);
onPause:到這一步是可見但不可互動的,系統會停止動畫等消耗CPU的事情。從上文的描述已經知道,應該在這裡保存你的一些數據,因為這個時候你的程序的優先級降 低,有可能被系統收回。這裡保存的數據,應該在onResume裡唸出來。
onStop:變得不可見,被下一個activity覆蓋了
onDestroy:這是Activity被kill前最後一個被調用方法了,可能是其他類調用finish方法或者是系統為了節省空間將它暫時性的乾掉,可以用isFinishing()來判斷它,如果你有 一個Progress Dialog在線程中運行,請在onDestroy裡把他cancel掉,不然等線程結束的時候,調用Dialog的cancel方法會拋異常。
onPause,onstop, onDestroy,三種狀態下 activity都有可能被系統kill 掉。
三、Activity之間的通訊
在 Android 中,不同的 Activity 實例可能運行在一個進程中,也可能運行在不同的進程中。因此我們需要一個特別的機制來幫助我們在 Activity 之間傳遞訊息。 Android 中透過 Intent 物件來表示一則訊息,一個 Intent 物件不僅包含有這個訊息的目的地,還可以包含訊息的內容,這好比一封 Email,其中不僅應該包含收件位址,還可以包含具體的內容。對於一個 Intent 對象,訊息「目的地」是必須的,而內容則是可選項。
Intent負責對操作的動作、動作涉及資料、附加資料進行描述,Android則根據此Intent的描述,負責找到對應的元件,將 Intent傳遞給呼叫的元件,並完成元件的呼叫。因此,Intent在這裡起著一個媒體中介的作用,專門提供元件互相調用的相關訊息,實現呼叫者與被呼叫者之間的解耦。
Android需要解析的是那些間接Intent,透過解析,將 Intent對應到可以處理此Intent的Activity、IntentReceiver或Service。 Intent解析機制主要是透過尋找已註冊在AndroidManifest.xml中的所有IntentFilter及其中定義的Intent,最終找到匹配的Intent。
四、Activity 的 Intent Filter
Intent Filter 描述了一個元件願意接收什麼樣的 Intent 對象,Android 將其抽象化為 android.content.IntentFilter 類別。在 Android 的 AndroidManifest.xml 設定檔中可以透過
當使用 startActivity(intent) 來啟動另外一個 Activity 時,如果直接指定 intent 物件的 Component 屬性,那麼 Activity Manager 將試圖啟動其 Component 屬性指定的 Activity。否則 Android 將透過 Intent 的其它屬性從安裝在系統中的所有 Activity 中尋找與之最匹配的一個啟動,如果沒有找到合適的 Activity,應用程式會得到一個系統拋出的例外。這個配對的過程如下:
五、Activity的棧式管理
Android針對Activity的管理使用的是棧,就是說某一個時刻只有一個Activity處在被頂棧,當這個Activity被銷毀後,下面的Activity才有可能浮到堆疊頂,或是有一個新的Activity被創建出來,則舊的Activity就被壓棧沉下去了。 Activity是Android程式的表現層。程式的每一個顯示畫面就是一個Activity。正在運行的Activity處在堆疊的最頂端,它是運行狀態的。
當在程式中呼叫 Activity.finish()方法時,結果和使用者按下 BACK 鍵一樣:它告訴 Activity Manager該Activity實例可以被「回收」。接著 Activity Manager 啟動處於堆疊第二層的 Activity ,把原 Activity 壓入到堆疊的第二層,從 Running 狀態轉到 Paused 狀態。
六、Activity的載入模式
standard、singleTop、singleTask、singleInstance(其中前兩個是一組、後兩個是一組),預設為standard
standard:就是intent會發送給新的實例,所以每次跳轉都會產生新的activity。
singleTop:也是發送新的實例,但不同standard的一點是,在請求的Activity正好位於棧頂時(配置成singleTop的Activity),不會構造新的實例
singleTask:和後面的singleInstance都只建立一個實例,當intent到來,需要建立設定為singleTask的Activity的時候,系統會檢查堆疊裡面是否已經有該Activity的實例。如果有直接將intent發送給它。
singleInstance:
首先說明task這個概念,Task可以認為是一個堆疊,可放入多個Activity。例如啟動一個應用,那麼Android就創建了一個Task,然後啟動這個應用的入口Activity,那在它的介面上呼叫其他的Activity也只是在這個task裡面。那如果在多個task中共用一個Activity的話怎麼辦呢。舉個例來說,如果開啟一個導遊服務類的應用程序,裡面有個Activity是開啟GOOGLE地圖的,當按下home鍵退回到主菜單又啟動GOOGLE地圖的應用時,顯示的就是剛才的地圖,實際上是同一個Activity,實際上這就引入了singleInstance。 singleInstance模式就是將該Activity單獨放入一個堆疊中,這樣這個棧中只有這一個Activity,不同應用的intent都由這個Activity接收和展示,這樣就做到了共享。當然前提是這些應用程式都沒有被銷毀,所以剛才是按下的HOME鍵,如果按下了回傳鍵,則無效。
七、Activity的跳轉
Activity跳轉,無回結果
這是最簡單的Activity跳躍方式。從一個Activity啟動另一個Activity,直接startActivity(new Intent(當前Activity.this, 下一Activity.class))。
Activity跳轉,回傳資料/結果
需要傳回資料或結果的,則使用startActivityForResult (Intent intent, int requestCode),requestCode的值是自訂的,用於識別跳轉的目標Activity。跳轉的目標Activity要做的就是傳回資料/結果,setResult(int resultCode)只回傳結果不帶數據,或是setResult(int resultCode, Intent data)都回傳!而接收回傳的資料/結果的處理函數是onActivityResult(int requestCode, int resultCode, Intent data),這裡的requestCode就是startActivityForResult的requestCode,resultCode就是setResult裡面的resultCode,傳回的資料在裡面。
** 注意,在setResult後,要呼叫finish()銷毀目前的Activity,否則無法回到原來的Activity,就無法執行原來Activity的onActivityResult函數,看到目前的Activity沒反應。