Activity 初步(大部分翻譯自SDK)

(內容:如何建立、使用activity; activity生命週期。) java

Activity

Activity 是一個爲用戶提供交互接口的組件,每一個activity都會有一個window來顯示本身的界面。 應用能夠由多個互相「弱關聯」的activity組成,activity能夠啓動另一個activity, 有activity啓動的時候,當前的就會被暫停,系統把被暫停的activity存儲在一個FILO(先進後出)的棧中,當用戶點擊「back」時,位於棧頂的activity就會從新被顯示出來。 android

Activity 提供一系列的接口,在生命週期運行到特定的階段時會通知相應的接口,用戶在這些回調接口中作當前階段的處理。例如,在create時初始化應用的資源,stop時做資源的釋放。 數組

1 建立Activity

建立一個activity必須繼承爲Activity的子類,並覆蓋所須要生命週期的回調方法。比較重要的2個方法: app

onCreate(): 系統在建立activity時會調用,必需要覆蓋的方法。應該在此階段作初始化工做,layout必定要在這裏被初始化:調用setContentView() 設置activity的界面。 ide

onPause(): 用戶離開這個activity時系統調用的第一個方法,鑑於用戶不必定會再返回這個activity,應該作數據持久化的處理。 佈局

生命週期的其餘部分會在後面繼續討論。 this


1.1 創建用戶界面

用戶界面由含有層級關係的一個或多個View組成,每個View控制屏幕的一個矩形區域,且能夠相應用戶的操做。術語Widgets表示用戶可見或可交互的ViewLayout 則是ViewGroup,它包含的view提供佈局的規則。 google

android已經提供了一系列的組件如buttontextview等,咱們能夠直接使用,也能夠繼承View 或 ViewGroup,實現特定功能的控件。 spa

將佈局傳遞給activity通常的作法是在xml中定義本身的界面,而後使用setContentView()佈局。 .net


1.2 在Manifest中聲明activity

Activity必須在所屬應用的Manifest.xml中聲明,否則系統會找不到,最簡單的聲明能夠按照如下格式:

<manifest ... >
  <application ... >
      <activity android:name=".ExampleActivity" />
      ...
  </application ... >
  ...
</manifest >

android:name對應這個activity的路徑,包名和java名。還有其餘可選的屬性如labeltheme等。

在聲明以後,還能夠爲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

        在一個activity中,使用startActivity()啓動另一個activity,爲了註明要跳轉到哪裏activity,須要使用Intent: 

//從當前的activity跳到「YourActivity」
    Intent intent = new Intent(this, YourActivity.class); 
    startActivity(intent);

        除了直接指定class名,android提供了另一種特殊的方式:

       你的應用可能須要別的程序爲你完成一些特定操做,只要爲Intent指定一個Action,系統就會爲你找到接收這個actionactivity。(Intent的最精華的做用在於此,實現鬆耦合

       例如你的程序須要發送一封郵件給指定的收件人,intent須要一個action和 收件人的列表做爲data,Email編輯界面會爲你加載這些數據,這裏的recipientArray會被讀取並顯示在Email的收件人編輯框中

Intent intent = new Intent(Intent.ACTION_SEND);
    intent.putExtra(Intent.EXTRA_EMAIL,recipientArray);
    startActivity(intent);


2.1 啓動帶有返回結果的activity

     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...
        }
    }
}

3 關閉activity

finish() 和 finishActivity()均可以關閉一個activity,但google建議:除了必須時,不要直接調用這些接口,應該交由系通通一管理生命週期。


4 管理生命週期

一個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() 到 onDestroy()是一個完整的週期 。 應該在onCreate()作初始化(layout等),在onDestroy()中釋放全部佔用的資源(如正在工做的線程、bitmap等)。
  • 從onStart()到 onPause()被調用前 屬於可見的週期。用戶能夠看見activity的界面並與之交互。若是當前界面再也不可見,onStop()將會被調用。在這2個方法之間,應該管理和UI顯示相關的數據資源。如:onStart()註冊一個receiver監聽數據的變化,在onStop()時應註銷它,由於界面已經不可見,不須要再更新。
  • 從onResume()到 onPause()被調用,屬於前臺(foreground)的週期。activity處於全部其餘activity以前,並能接收用戶輸入。由於activity常常被高頻率的切換,前臺activity被轉入後臺(如彈出一個非全屏的dialog),這2個方法應用於處理一些輕量級的操做,防止界面切換出現卡頓。


生命週期的經典圖示:


生命週期方法的總結:

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。


5 保存activity狀態

activity 的回調方法 onSaveInstanceState() 能夠用於保存activity狀態,方法提供Bundle參數給咱們保存數據,若是系統kill掉了這個activity,用戶return回去的時候,咱們能夠經過onCreate()(或者onRestoreInstanceState())的Bundle參數提取出這些數據。

onSaveInstanceState()默認保留各類View的顯示狀態(checkbox是否勾上等),咱們須要作的是保存與界面綁定的一些變量值,如記錄checkbox值的數組,而且確保layout中的重要view都有本身的id,不然它的狀態沒法保存。若是覆蓋此方法,應該在開始便調用super.onSaveInstanceState(),由於它默認會幫組咱們記錄view的狀態

相關文章
相關標籤/搜索