編輯:Android編程入門
這裡的內容參考官方的文檔,這篇文章的目的不是去總結Activity是如何啟動,如何創造,以及暫停和銷毀的,而是從實際開發中分析在Activity各個生命周期,我們應該處理的內容。
由圖可以看出 ,在一個activity的生命周期中,系統會像金字塔模型一樣去調用一系列的生命周期回調函數。在最上端是當前Activity的運行狀態,也就是說用戶徹底看到這個Activity時,Activity正處於onResume()
狀態。而且有圖可以看出來存在很長時間的狀態只有三個,Resume
, Paused
和Stoped
其他幾個狀態存在的時間比較短暫,很快就會進入其他狀態。而Create
方法作為創建Activity時調用的方法,也是極為重要的回調方法。下面我們重點考慮這個四個方法的回調時機,並考慮在其中應該填入的功能。
onCreate
啟動一個Activity,Android一般有2種方式,即通過點擊主界面的應用圖標啟動Activity和在其他Activty中用startActivity
之類的方法啟動新的Activity.但不管哪種方式,創建新的Activity時都會調用onCreate()
方法。我們必須來實現程序啟動所需要的各種基本邏輯。比如聲明UI元素,定義成員變量,配置UI等等。
注意在onCreate
裡面盡量少做事情,避免程序啟動太久看不到界面。因為onCreate
執行完事之後,用戶並不能看到界面,直到經歷了onStart
之後調用onResume
進入Resume狀態,這時才是用戶看到的界面,所以如何onCreate
中做的事情太多,則程序會啟動的比較久。一般新建一個Activity會自動生成onCreate
,其代碼如下:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
}
這裡我們可以看到onCreate
回調方法中傳入的參數是Bundle類型的savedInstanceState。這是參數是用來保存Activity和恢復Activity的。當Activity是因為用戶點擊Back按鈕或者是activity通過調用finish()結束自己時,系統就丟失了對Activity實例的引用,因為這一行為意味著不再需要這個activity了。然而,如果因為系統資源緊張而導致Activity的Destory, 系統會在用戶回到這個Activity時有這個Activity存在過的記錄,系統會使用那些保存的記錄數據(描述了當Activity被Destory時的狀態)來重新創建一個新的Activity實例。那些被系統用來恢復之前狀態而保存的數據被叫做 "instance state"
,它是一些存放在Bundle對象中的key-value pairs。這是官方對instance state的解釋。一般,我們可以不用管它,因為他會自動保存每個View視圖的信息,然後當恢復的時候,會自動恢復到之前的狀態。但我們有時候也會讓他保存一些我們希望他保存的東西,比如記錄用戶狀態的成員變量信息,這時我們需要用到onSavaInstacneState()
方法,當用戶離開Activity時,系統會調用它。當系統調用這個函數時,系統會在Activity被異常Destory時傳遞 Bundle 對象,這樣我們就可以增加額外的信息到Bundle中並保存到系統中。若系統在Activity被Destory之後想重新創建這個Activity實例時,之前的Bundle對象會(系統)被傳遞到你我們activity的onRestoreInstanceState()
方法與 onCreate() 方法中。
為了給Activity保存額外的狀態信息,你必須實現onSaveInstanceState() 並增加key-value pairs到 Bundle 對象中,例如:
static final String STATE_SCORE = "playerScore";
static final String STATE_LEVEL = "playerLevel";
...
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the user's current game state
savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
然後恢復Activity的時候,我們先判斷一下時候是第一次創建還是恢復之前被Destory
的Activity,可以參見下面的例子,在onCreate方法裡恢復數據
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // Always call the superclass first
// Check whether we're recreating a previously destroyed instance
if (savedInstanceState != null) {
// Restore value of members from saved state
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
} else {
// Probably initialize members with default values for a new instance
}
...
}
我們也可以選擇實現 onRestoreInstanceState()
,而不是在onCreate
方法裡面恢復數據。 onRestoreInstanceState()
方法會在 onStart()
方法之後執行. 系統僅僅會在存在需要恢復的狀態信息時才會調用 onRestoreInstanceState()
,因此不需要檢查 Bundle 是否為null。
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);
// Restore state members from saved instance
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
}
onPause
Paused
狀態是一個長期保持的靜態狀態,Activity有時候會被其他可見的組件阻塞,從而導致當前的activity進入Pause
狀態。例如當打開一個對話框的時候,之前的 Activity會被暫停,但只要之前的Activity仍然被部分可見,這個activity就會會一直處於Paused
狀態。然而,一旦之前的activity被完全阻塞並不可見時,則其會進入Stop
狀態.activity一旦進入paused
狀態,系統就會調用activity中的onPause()
方法, 該方法中可以停止不應該在暫停過程中執行的操作,如暫停視頻播放;或者保存那些有可能需要長期保存的信息。如果用戶從暫停狀態回到當前activity,系統應該恢復那些數據並執行onResume()
方法。
通常在onPause()回調方法中做以下事情
停止動畫或者是其他正在運行的操作,那些都會導致CPU的浪費.
提交在用戶離開時期待保存的內容(例如郵件草稿).
釋放系統資源,例如broadcast receivers, sensors (比如GPS), 或者是其他任何會影響到電量的資源。
例如, 如果程序使用Camera,onPause()
會是一個比較好的地方去做那些釋放資源的操作。
@Override
public void onPause() {
super.onPause(); // Always call the superclass method first
// Release the Camera because we don't need it when paused
// and other activities might need to use it.
if (mCamera != null) {
mCamera.release()
mCamera = null;
}
}
不應該使用onPause()
來執行CPU-intensive 的工作,例如寫數據到DB,因為它會導致切換到下一個activity變得緩慢。
onResume
當用戶從Paused
狀態恢復activity時,系統會調用onResume()
方法。請注意,系統每次調用這個方法時,activity都處於前台,包括第一次創建的時候。所以,應該實現onResume()
來初始化那些在onPause
方法裡面釋放掉的組件,並執行那些activity每次進入Resumed state
都需要的初始化動作 (例如開始動畫與初始化那些只有在獲取用戶焦點時才需要的組件)
下面的onResume()
的例子是與上面的onPause()
例子相對應的。
@Override
public void onResume() {
super.onResume(); // Always call the superclass method first
// Get the Camera instance as the activity achieves full user focus
if (mCamera == null) {
initializeCamera(); // Local method to handle camera init
}
}
onStop
在下面一些關鍵的場景中會涉及到停止與重啟:
用戶打開最近使用app的菜單並從我們的app切換到另外一個app,這個時候我們的app是被停止的。如果用戶通過手機主界面的啟動程序圖標或者最近使用程序的窗口回到我們的app,那麼我們的activity會重啟。
用戶在我們的app裡面執行啟動一個新activity的操作,當前activity會在第二個activity被創建後stop。如果用戶點擊back按鈕,第一個activtiy會被重啟。
用戶在使用我們的app時接收到一個來電通話.
Activity類提供了onStop()
與onRestart()
方法來允許在activity停止與重啟時進行調用。不同於暫停狀態的部分阻塞UI,停止狀態是UI不再可見並且用戶的焦點轉移到另一個activity中.
在onStop
方法activity不再可見,並且應該釋放那些不再需要的所有資源。一旦activity停止了,系統會在需要內存空間時摧毀它的實例(和棧結構有關,通常back操作會導致前一個activity被銷毀)。極端情況下,系統會直接殺死我們的app進程,並不執行activity的onDestroy()
回調方法, 因此我們需要使用onStop()
來釋放資源,從而避免內存洩漏。
上面我們已經說了在onPause()
中我們是不建議進行數據庫讀寫等操作的,而應該把它放到onStop()
中,讓該方法來執行一些CPU密集的操作。
就如同onResume
方法裡來初始化被onPause
方法中關閉的資源,我們也應該在onStart
方法裡來初始化在onStop
方法裡關閉的資源。
當系統Destory我們的activity,它會為activity調用onDestroy()方法。因為我們會在onStop方法裡面做釋放資源的操作,那麼onDestory方法則是我們最後去清除那些可能導致內存洩漏的地方。因此需要確保那些線程都被destroyed並且所有的操作都被停止。
至此,Activity生命周期中,我們應該做的工作就敘述完畢了。
1. 輪播控件的組成部分 我們以知乎日報Android客戶端的輪播控件為例,分析一下輪播控件的主要組成: &
activity_ui6.xml<?xml version=1.0 encoding=utf-8?><GridView xmlns:android=ht
Android 廣播接收器(Broadcast Receivers)廣播接收器用於響應來之其他應用程序或者系統的廣播消息。這些消息有時被稱為事件或者意圖。
讓我們來簡單了解下Android Studio中不同目錄(文件)的位置和用途。首先看下一個App的最簡單的目錄結構 OK,我們這麼看,第一,把這麼多