(內容:如何建立、使用activity; activity生命週期。) java
Activity 是一個爲用戶提供交互接口的組件,每一個activity都會有一個window來顯示本身的界面。 應用能夠由多個互相「弱關聯」的activity組成,activity能夠啓動另一個activity, 有activity啓動的時候,當前的就會被暫停,系統把被暫停的activity存儲在一個FILO(先進後出)的棧中,當用戶點擊「back」時,位於棧頂的activity就會從新被顯示出來。 android
Activity 提供一系列的接口,在生命週期運行到特定的階段時會通知相應的接口,用戶在這些回調接口中作當前階段的處理。例如,在create時初始化應用的資源,stop時做資源的釋放。 數組
建立一個activity必須繼承爲Activity的子類,並覆蓋所須要生命週期的回調方法。比較重要的2個方法: app
onCreate(): 系統在建立activity時會調用,必需要覆蓋的方法。應該在此階段作初始化工做,layout必定要在這裏被初始化:調用setContentView() 設置activity的界面。 ide
onPause(): 用戶離開這個activity時系統調用的第一個方法,鑑於用戶不必定會再返回這個activity,應該作數據持久化的處理。 佈局
生命週期的其餘部分會在後面繼續討論。 this
用戶界面由含有層級關係的一個或多個View組成,每個View控制屏幕的一個矩形區域,且能夠相應用戶的操做。術語Widgets表示用戶可見或可交互的View,Layout 則是ViewGroup,它包含的view提供佈局的規則。 google
android已經提供了一系列的組件如button、textview等,咱們能夠直接使用,也能夠繼承View 或 ViewGroup,實現特定功能的控件。 spa
將佈局傳遞給activity通常的作法是在xml中定義本身的界面,而後使用setContentView()佈局。 .net
Activity必須在所屬應用的Manifest.xml中聲明,否則系統會找不到,最簡單的聲明能夠按照如下格式:
<manifest ... > <application ... > <activity android:name=".ExampleActivity" /> ... </application ... > ... </manifest >
android:name對應這個activity的路徑,包名和java名。還有其餘可選的屬性如label,theme等。
在聲明以後,還能夠爲activity加上其餘屬性,若是這個activity是用在顯示在桌面上的主程序,就應該加上如下內容,否則程序找不到主入口了:
<activity android:name=".ExampleActivity" android:icon="@drawable/app_icon"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
在一個activity中,使用startActivity()啓動另一個activity,爲了註明要跳轉到哪裏activity,須要使用Intent:
//從當前的activity跳到「YourActivity」 Intent intent = new Intent(this, YourActivity.class); startActivity(intent);
除了直接指定class名,android提供了另一種特殊的方式:
你的應用可能須要別的程序爲你完成一些特定操做,只要爲Intent指定一個Action,系統就會爲你找到接收這個action的activity。(Intent的最精華的做用在於此,實現鬆耦合)
例如你的程序須要發送一封郵件給指定的收件人,intent須要一個action和 收件人的列表做爲data,Email編輯界面會爲你加載這些數據,這裏的recipientArray會被讀取並顯示在Email的收件人編輯框中:
Intent intent = new Intent(Intent.ACTION_SEND); intent.putExtra(Intent.EXTRA_EMAIL,recipientArray); startActivity(intent);
startActivity()只是告訴系統要啓動一個activity, 但有些狀況下,咱們還須要啓動的activity爲咱們完成一項工做後返回結果和數據,能夠用如下方法:
startActivityForResult(Intent i, int requestCode); //requestCode 標記這個activity例子,須要用戶從電話本選取一個聯繫人並返回給當前activity作處理:
private void pickContact() { // Create an intent to "pick" a contact, as defined by the content provider URI Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI); startActivityForResult(intent, PICK_CONTACT_REQUEST); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // If the request went well (OK) and the request was PICK_CONTACT_REQUEST if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) { // Perform a query to the contact's content provider for the contact's name Cursor cursor = getContentResolver().query(data.getData(), new String[] {Contacts.DISPLAY_NAME}, null, null, null); if (cursor.moveToFirst()) { // True if the cursor is not empty int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME); String name = cursor.getString(columnIndex); // Do something with the selected contact's name... } } }
finish() 和 finishActivity()均可以關閉一個activity,但google建議:除了必須時,不要直接調用這些接口,應該交由系通通一管理生命週期。
一個activity的生命週期直接受到其餘activity、當前任務或back stack的影響,經過生命週期的接口對activity進行管理,能夠創建更加健壯和靈活的程序。
如下回調方法對應着生命週期的幾個狀態:
public class ExampleActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // The activity is being created. } @Override protected void onStart() { super.onStart(); // The activity is about to become visible. } @Override protected void onResume() { super.onResume(); // The activity has become visible (it is now "resumed"). } @Override protected void onPause() { super.onPause(); // Another activity is taking focus (this activity is about to be "paused"). } @Override protected void onStop() { super.onStop(); // The activity is no longer visible (it is now "stopped") } @Override protected void onDestroy() { super.onDestroy(); // The activity is about to be destroyed. } }
若是覆蓋以上的所有方法,咱們就能夠完整地管理activity 生命週期的3個階段(但實際上某些時候只須要其中幾個),在不一樣階段應該作相應級別的處理:
生命週期的經典圖示:
onCreate: activity被建立時調用。初始化靜態數據的操做:建立view,爲list綁定數據等。它有一個Bundle做爲參數,存放 着這個activtiy以前的狀態(onSaveInstanceState())。以後調用的必定是onStart()。
onRestart: activity被stop後,還原時調用。以後調用的必定是onStart()。
onStart: 在activity顯示在屏幕以前調用。若是activity轉到前臺會調用onResume(),若是界面被遮擋則進入onStop()。
onResume(): 在能夠和用戶交互以前調用。 activity已經被置於棧頂。 onPause()在其後調用。
onPause(): 在另外一個activity即將resume時被調用。通常用來保存數據和中止一些消耗CPU的操做等。鑑於界面正 在跳轉,爲了避免阻塞,這裏的操做應該越快完成越好。 activtiy若回到顯示狀態將會調onResume(), 不然 隨後調用onStop()讓它消失在屏幕上。
onStop(): 在界面徹底被遮擋住前調用。 這時,可能activity即將被destroy,或者其餘activity resume並遮住了它。 activtiy若將從新顯示則調用onRestart(), 不然進入onDestroy() 將其毀滅。
onDestroy(): activity即將被滅掉了。這是最後一個被調用的週期方法。 致使destroy的多是用戶指定finish(), 或者系統 爲了節省空間。 isFinishing()能夠區分這兩種狀況。
注意:onPause()方法實際上是系統必定會調用的最後一個生命週期方法,onStop(), onDestroy()都不保證必定能調到,因此重要的事情應該在onPause()裏面完成(保存數據等),且選擇必須保留的數據,避免阻塞下一個activity。
activity 的回調方法 onSaveInstanceState() 能夠用於保存activity狀態,方法提供Bundle參數給咱們保存數據,若是系統kill掉了這個activity,用戶return回去的時候,咱們能夠經過onCreate()(或者onRestoreInstanceState())的Bundle參數提取出這些數據。
onSaveInstanceState()默認保留各類View的顯示狀態(checkbox是否勾上等),咱們須要作的是保存與界面綁定的一些變量值,如記錄checkbox值的數組,而且確保layout中的重要view都有本身的id,不然它的狀態沒法保存。若是覆蓋此方法,應該在開始便調用super.onSaveInstanceState(),由於它默認會幫組咱們記錄view的狀態。