天天看點

解讀Android之Activity(1)基礎知識概述建立Activity啟動Activity關閉activity管理activity生命周期

本文翻譯自android官方文檔,結合自己測試,整理如下。

概述

一個Activity是能夠提供螢幕的應用程式元件,使用者可以通過該螢幕和程式進行互動。每個activity都被賦予一個視窗用于繪畫使用者接口,該視窗通常來說會覆寫整個螢幕,但是有時也會比螢幕小,顯示在其它視窗的上面。

一個程式通常有多個activities構成,而且需要一個

main

avtivity作為程式的入口當使用者第一次啟動該程式時。每一個activity都能夠啟動其它activities,當新的activity啟動時,前一個activity将進入

stopped

狀态,并儲存在back棧中。當啟動新的activity時,該activity會壓入棧頂并顯示給使用者。back棧滿足棧的後進先出原則,是以當使用者點選

BACK

鍵時,目前顯示的activity就會彈出棧頂(此時activity被銷毀),棧中的下一個activity成為棧頂,并顯示在螢幕上。

Activity有自己的生命周期,包括:建立,運作,停止,銷毀等,系統給我們提供了一些生命周期方法可以使我們在合适的生命周期中進行相關的操作。例如當activity停止時,我們需要釋放資源等。

下面我們就詳細讨論如何建立,使用,管理activity。

建立Activity

為了建立activity,我們必須繼承Activity類或者它的子類。在實作類中,我們必須覆寫相關的生命周期回調方法,這些回調方法是由系統在activity生命周期狀态轉換時被調用的。兩個最重要的回調方法:

  • onCreate()

    該方法是在建立Activity時被調用,通常我們需要在這裡初始化一些必要的元件。更重要的是,我們必須調用

    setContentView()

    設定activity和使用者互動的布局檔案。
  • onPause()

    當使用者離開activity,但是此時activity可見時,系統會調用該方法。此時我們需要儲存使用者會話中任何需要儲存的資料,這是由于使用者可能不在回到該activity中。

其它生命周期方法後續将詳細介紹。

實作使用者接口

activity使用者接口是由視圖的層次結構提供的,每一個視圖控制activity視窗上的一部分用于和使用者進行互動,例如一個視圖可能是一個按鈕。

系統提供了很多設計群組織布局的視圖,控件(

Widgets

)就是這樣的視圖,例如:按鈕,文本域,選擇框等等。布局(

Layouts

)是抽象類ViewGroup的實作類,例如:線性布局,相對布局等。同樣你也可以繼承View和ViewGroup實作自己的控件和布局。

定義布局最常用的方法是在xml檔案中定義。通過這種方法, 布局設計可以和代碼分開管理。我們可以通過

setContentView()

設定activity的布局檔案,該方法需要指定布局檔案的ID。當然,我們也可以在activity代碼中使用ViewGroup建立自己的視圖,然後通過

setContentView()

設定,該方法接收一個View參數。

在manifest檔案中聲明Activity

若要啟動Activity,需在AndroidManifest.xml聲明Activity,代碼如下:

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

在标簽

<activity>

中屬性

android:name

是必須的,它指定activity的類名(通常manifest中指定了包名,是以這裡隻需要

.ClassName

),當然在

<activity>

還有其他的屬性,這裡先不講。

一旦釋出程式的話,我們不應該再改變activity類名,這樣可能導緻一些功能出錯。

使用intent filters

在标簽

<activity>

可以通過子标簽

<intent-filter>

指定intent過濾器,該intent過濾器聲明其它元件如何啟動該activity。

當通過Android SDK工具建立第一個activity時,系統會自動生成一個帶

<intent-filter>

的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>
           

上面的

<intent-filter>

内容就是一個标準的啟動程式時第一個顯示activity的intent過濾器,即有該過濾器的activity表示程式的入口activity。是以在一個應用程式中隻有一個包含

main

action和

launcher

category的

<intent-filter>

若你不希望其它程式啟動你的程式的話,就不用設定任何的intent過濾器。在程式内部我們可以顯示地指定intent内容。

關于如何設定顯示和隐式intent以及它的各個屬性,我會專門用一章翻譯官方文檔内容,若有興趣的話,請持續關注我的部落格。

啟動Activity

我們可以通過

startActivity()

啟動另外一個activity,該方法傳遞一個Intent對象,用于描述啟動滿足條件的activity。系統根據Intent對象的要求進行選擇,滿足條件的activity都會呈現給使用者,即使是不在一個應用程式中的activity也可以啟動。

當我們啟動自己的應用程式内部的activity時,應該使用顯式啟動,這樣能夠減少解析Intent對象的過程,提高性能。顯式啟動需要在Intent對象中指定要啟動的類名,如:

Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);
           

然而,有時候我們的應用程式可能想要執行一些其他的任務,如發送郵件,短信等等。這種情況下我們的程式不具備這樣的activities,是以我們可以使用裝置上擁有該功能的其他程式的activities。這就需要使用隐式Intent方式。當有多個activities滿足條件時,系統将選擇權交給使用者,使用者來選擇一個合适的activity啟動。例如,發送郵件的intent設定如下:

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

putExtra()

中傳遞的是收件人郵箱。當完成郵件後,我們的activity又重新啟動。

啟動帶傳回結果的activity

有時候,我們可能希望從啟動的activity傳回結果,這種情況下可以通過

startActivityForResult()

啟動帶傳回結果的activity。而為了接收傳回結果,我們可以實作回調方法

onActivityResult()

處理傳回結果。當帶有傳回結果的activity處理完之後通過

setResult()

将結果發送到啟動它的activity中的

onActivityResult()

startActivityForResult()

接收兩個參數:

  1. Intent對象;
  2. int型請求碼,用于差別哪次請求。

onActivityResult()

傳遞三個參數:

  1. int型請求碼,和

    startActivityForResult()

    方法中第二個參數一緻;
  2. int型傳回碼,在将要啟動的activity中的

    setResult()

    設定,表示傳回結果是否成功;
  3. Intent對象,表示傳回結果資料

setResult()

接收兩個參數:

  1. int型傳回碼,用于判斷是否請求成功,可以使用系統提供值如:Activity.RESULT_OK;
  2. Intent對象,帶有傳回結果資料。

關于Activity之間通信的更多内容有興趣的可以參考我之前的文章:Activity之間通信

關閉activity

通過調用

finish()

方法可以關閉一個activity,也可以使用

finishActivity()

關閉之前啟動過的activity。通過這種方法關閉的activity,不再執行activity的各個生命周期方法(除了

onDestroy()

),而是直接在調用這兩個方法之後執行

onDestroy()

銷毀activity。

注意:更多的情況下,我們不應該使用這些方法關閉activity,這是因為activity有自己的生命周期,系統統一管理。我們自己關閉的話會對預期的使用者體驗産生不利的影響,隻有在極端情況下才使用這些方法來關閉activity。

管理activity生命周期

實作回調方法來管理activity的生命周期是開發健壯和靈活的應用程式的關鍵。

Activity本質上有三種狀态:

  1. Resumed/Running。activity在螢幕最前端,處于棧的最頂端,此時它處于可見并可和使用者互動的運作狀态。
  2. Paused。當Activity被另一個透明或者Dialog樣式的Activity覆寫時的狀态。此時它依然與視窗管理器保持連接配接,系統繼續維護其内部狀态,是以它仍然可見,但它已經失去了焦點故不可與使用者互動。或稱為暫停狀态。在系統極度缺少記憶體的情況下會被殺死。
  3. Stopped。當Activity被另外一個Activity完全覆寫(activity處于背景),失去焦點并不可見,或稱為停止狀态。處于該狀态的activity仍然是存活的,系統繼續維護其内部狀态,但是不再與視窗管理器保持連接配接。當系統需要記憶體時,該狀态的activity會被殺死。

若一個activity進入paused或stopped狀态,則系統可以調用

finish()

結束它,或者通過殺死它的程序。下次再啟動時,則不會儲存内部狀态。

也可以認為activity還有第四種狀态:Killed。 Activity被系統殺死回收或者沒有被啟動時處于Killed狀态。或稱為死亡狀态。

當一個Activity執行個體被建立、銷毀或者啟動另外一個Activity時,它在這四種狀态之間進行轉換,這種轉換的發生依賴于使用者程式的動作。

實作生命周期方法

當activity在以上4種狀态之間轉換時,就會調用相關的方法。我們可以通過覆寫這些方法來處理合适的工作。生命周期方法如下:

public class ExampleActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // activity被建立
    }
    @Override
    protected void onStart() {
        super.onStart();
        // activity将要可見
    }
    @Override
    protected void onResume() {
        super.onResume();
        // activity可見,執行後進入resumed狀态
    }
    @Override
    protected void onPause() {
        super.onPause();
        // 另一個activity獲得焦點,執行後進入paused狀态
    }
    @Override
    protected void onStop() {
        super.onStop();
        // activity不可見,執行後進入stopped狀态。
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        // activity将要銷毀
    }
}
           

注意覆寫這些方法時必須首先調用父類對應的方法,如上。

通過實作以上方法,我們可以監控activity生命周期中的以下三個嵌套時間段:

  • entire lifetime

    這個時間段在

    onCreate()

    onDestroy()

    之間,也就是涉及整個生命周期。通常需要在

    onCreate()

    設定初始化内容,在

    onDestroy()

    釋放系統資源。例如在activity中啟動線程的話,一般要在

    onCreate()

    啟動,在

    onDestroy()

    結束線程。
  • visible lifetime

    這個時間段在

    onStart()

    onStop()

    之間。在這個時間段,我們能看到activity界面并能和它進行互動。例如調用

    onStop()

    方法後該activity不再可見。在這個時間段我們能夠給activity提供資源,用于處理和使用者的互動。系統可能會多次調用這兩個方法,原因在于activity會頻繁地處于顯示和隐藏狀态。
  • foreground lifetime

    這個時間段在

    onResume()

    onPause()

    之間。在這個時間段,activity處于其它任何activity之上,完全可見,并獲得焦點。activity可能通過調用

    onPause()

    方法頻繁進出這個時間段。正是因為這個原因,要避免在

    onResume()

    onPause()

    處理耗時的操作,減少使用者等待的時間。

在android中,Activity的生命周期交給系統統一管理,所有的Activity 都是平等的。下圖給出了生命周期處理過程,包含了Activity生命周期的七大方法。

解讀Android之Activity(1)基礎知識概述建立Activity啟動Activity關閉activity管理activity生命周期

Activity執行個體是由系統自動建立,并在不同的狀态期間回調相應的方法。下面具體描述了以上七種方法。

方法 描述 之後是否能被殺死 下一步調用方法

onCreate()

activity被建立時調用,一般可以在該方法中初始化基本資訊,例如初始化UI元件activity。該方法傳遞一個Bundle對象,該對象儲存activity之前的狀态,即儲存該Activity被銷毀之前的資訊(後續有詳細介紹)。

onStart()

onRestart()

onStop()

之後調用,表示當進入stopped狀态的activity重新啟動。

onStart()

onStart()

activity将要可見前調用,若activity進入前台則調用

onResumed()

;若隐藏則調用

onStop()

onResume()

onStop()

onResume()

activity将要和使用者互動前調用,處于棧頂位置,并處于運作狀态(Resumed)

onPause()

onPause()

系統将要啟動其它activity時調用,通常用于送出永久性儲存資料,停止其它消耗CPU的操作等。它将盡可能地快速被執行,因為隻有它執行完之後下一個activity才會啟動。若activity傳回前台則調用

onResume()

;若activity不再可見則調用

onStop()

onResume()

onStop()

onStop()

當activity完全不可見時調用。原因可能是系統已經銷毀,或者被另一個activity完全覆寫。若activity将要傳回和使用者互動的話,調用

onRestart()

;若activity将要銷毀則調用

onDestroy()

onRestart()

onDestroy()

onDestroy()

在activity被銷毀之前。這是最後一個生命周期方法。調用原因可能有如下兩個:調用

finish()

,或系統暫時銷毀該activity的執行個體節省空間。

第三清單明系統是否會在對應的方法執行完殺死帶有該activity的程序,而不是繼續執行activity其它的生命周期方法。

onPause()

,

onStop()

onDestroy()

标記為是。

onPause()

是第一個可能被殺死的情況,這個方法也是activity所在的程序被殺死之前保證被執行的最後一個方法(若系統記憶體嚴重不足的話,後兩個方法不一定被執行)。是以,我們需要在

onPause()

方法中儲存需要永久儲存的資料,但是必須選擇哪些資訊是必須儲存的,這是因為,若在該方法中執行耗時的操作,則會阻止另一個activity進入前台,并會降低使用者體驗。

注意:activity被殺死也并不是完全按照上面的情況,也有可能在系統記憶體嚴重不足的情況下被殺死,這一部分将在另外一個章節詳細介紹,有興趣的可以持續關注一下我的部落格。

儲存activity狀态

在前面也提到了activity在paused或stopped狀态時,系統會儲存它的内部狀态。這是因為Activity對象仍然被儲存在記憶體,包括所有的資訊,成員變量以及狀态。是以,當activity從paused或stopped狀态轉換到resumed狀态時,這些狀态自動恢複,而不用我們進行恢複。

然而,若因為系統記憶體不足而銷毀Activity時,系統不能再簡單地根據它的狀态而重新啟動它,而是必須重新建立activity。但是使用者可能不知道系統已經銷毀activity,仍然想從剛才的狀态打開activity。這種情況下,我們就要保證使用者的重要資訊不能丢失,必須儲存起來,可以通過另外的回調方法

onSaveInstanceState()

實作儲存。

在activity可能被系統銷毀(非使用者主動,例如1.按下HOME鍵時;2.按下電源按鍵(關閉螢幕)時;3.被另一個Activity執行個體覆寫時;4.螢幕切換或其它配置變化時)時,該Activity就會回調

onSaveInstanceState()

儲存目前UI狀态,當然你也可以在這裡儲存臨時資料。該方法接收一個Bundle對象,我們可以使用該對象儲存鍵值對,例如使用該對象的

putString()

,

putInt()

等。然後,若系統殺死了該activity或應用程式程序,同時使用者又重新回到該activity的話,系統就會将儲存的Bundle對象傳遞給

onCreate()

onRestoreInstanceState()

。使用這兩個中的任何一個都能将資料恢複

onCreate()

不能自動恢複UI狀态,而

onRestoreInstanceState()

可以通過調用父類方法實作自動恢複)。當沒有資料儲存的時候Bundle傳遞的值為null(第一次建立activity就是這種情況)。下圖就描述了上面的這種情況:

解讀Android之Activity(1)基礎知識概述建立Activity啟動Activity關閉activity管理activity生命周期

注意:

  • 在activity銷毀之前不能保證一定調用

    onSaveInstanceState()

    ,因為有些情況下,沒必要儲存狀态,例如使用者明确指出銷毀該activity(可以通過BACK鍵)。
  • 若系統調用了

    onSaveInstanceState()

    ,則肯定在

    onStop()

    之前調用,可能在

    onPause()

    之前調用。一般調用順序為:
    1. 調用onPause()方法暫停目前Activity;
    2. 調用onSaveInstanceState()方法;
    3. 依次調用onStop(),onDestroy()銷毀該Activity執行個體;
    4. 依次調用onCreate(),onStart()重新啟動該Activity執行個體;
    5. 調用onRestoreInstanceState()方法恢複儲存的資料;
    6. 調用onResume()啟動。
  • onRestoreInstanceState()

    不一定被調用。當Activity确實被系統銷毀了才會回調onRestoreInstanceState()方法(重新執行個體化在onStart()之後)。而如果僅僅是停留在有這種可能性的情況下,則該方法不會被調用。

然而,即使我們沒有實作

onSaveInstanceState()

,activity的一些狀态也會被儲存,這是因為Activity類預設實作了該方法。預設情況下該方法實作了所有View對象的

onSaveInstanceState()

,該方法和activity中的一樣,也是用來儲存對應View的狀态。Android中大部分控件都實作了該方法,以便UI發生可見的變化時能夠自動儲存并在activity重新建立時恢複。例如EditText控件能夠儲存使用者輸入的任何資訊,CheckBox能夠儲存是否被選中等。我們唯一需要做的就是給這些控件提供一個唯一的ID(使用`android:id屬性),若不提供ID的話,系統不會儲存該控件狀态。

若我們不想讓系統儲存某個控件的狀态,則可以設定

android:saveEnabled

為false或調用

setSaveEnabled()

方法。

盡管系統預設實作了

onSaveInstanceState()

來儲存關于UI的有用資訊,但是我們通常仍然需要覆寫該方法來儲存一些其他的預設不會被儲存的額外資訊。在覆寫該方法時我們首先要調用父類的方法,以便能夠儲存UI狀态。同樣在覆寫

onRestoreInstanceState()

我們應該也先調用父類的方法來自動恢複UI狀态。

注意:

  • 由于

    onSaveInstanceState()

    不能保證肯定被執行,是以在這裡儲存的資料應該都是瞬時的UI狀态,而不應該儲存永久資料。對于永久資料應該在

    onPause()

    中儲存。

一個測試程式恢複資料能力的辦法是切換裝置螢幕。當螢幕被切換時,系統就會銷毀activity并重新建立。僅此原因,完全恢複activity狀态是非常重要的,原因很簡單,使用者經常會不斷地切換螢幕。

處理配置變化

一些配置可能在程式運作時發生變化,如螢幕變化,鍵盤可見性,語言等。當發生配置變化時,系統就會重新建立運作的activity(系統調用

onDestroy()

之後立刻調用

onCreate()

)。這種設計的好處在于,當配置發生變化時,我們的程式可以自動适應新的配置,當然前提是我們提供系統可選擇的資源,例如不同螢幕顯示不同的布局檔案。

處理這種儲存和恢複資料的方法就是使用上一部分讨論過的

onSaveInstanceState()

onRestoreInstanceState()

(或

onCreate()

)。

然而,有時候重新開機并恢複資料是非常耗時的,這樣會造成使用者體驗下降,處理這種問題,有兩種可選的方案:

  • 在配置改變時保留一個對象

    當配置發生變化時,我們運作重新啟動activity,但是要儲存一個狀态對象給新的activity。

  • 自己處理配置改變

    當配置發生變化時,我們不允許activity重新啟動,而是接受一個回調,我們可以在回調方法裡更新必要的資訊。

下面分别介紹這兩種情況。

在配置改變時保留一個對象

如果允許重新啟動activity的話,我們需要恢複大量的資料,重建立立網絡連接配接等,這樣完全的重新啟動就會降低使用者體驗。同時,通過Bundle對象儲存資料的話不能處理大的對象(如bitmaps)以及序列化反序列化等等,這些都會消耗大量的記憶體空間。在這樣的情況下,我們可以通過Fragment緩解。該fragment可以包含狀态對象的引用,友善我們恢複。

當由于配置發生變化而造成系統銷毀我們的activity時,我們标記儲存狀态的fragments沒有被銷毀,是以,可以使用該fragment完成資料恢複。

為了在配置變化時,在fragment中儲存資料,我們需要完成以下工作:

  1. 繼承Fragment類,聲明狀态對象的引用;
  2. 在fragment被建立的時候調用

    setRetainInstance(boolean)

  3. 添加fragment到activity;
  4. 當activity被重新開機時,用FragmentManager檢索該fragment,然後完成恢複。

例如,我們的fragment可以定義如下:

public class RetainedFragment extends Fragment {

    // data object we want to retain
    private MyDataObject data;

    // this method is only called once for this fragment
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // retain this fragment
        setRetainInstance(true);
    }

    public void setData(MyDataObject data) {
        this.data = data;
    }

    public MyDataObject getData() {
        return data;
    }
}
           

警告:雖然我們可以在fragment儲存任何對象,但是我們絕對不能儲存一個和activity關聯的對象,例如:Drawable,Adapter,View或者其他和Context關聯的對象。若這樣做了,所有的View和初始的activity資源都會造成記憶體洩漏(應用程式一直持有它們,不能被GC回收)。

完成了fragment,下面我們可以向activity中添加該fragment,進而能夠完成儲存和恢複,例如:

public class MyActivity extends Activity {

    private RetainedFragment dataFragment;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // find the retained fragment on activity restarts
        FragmentManager fm = getFragmentManager();
        dataFragment = (RetainedFragment) fm.findFragmentByTag(“data”);

        // create the fragment and data the first time
        // 建立一個不帶視圖的fragment。。。。
        if (dataFragment == null) {
            // add the fragment
            dataFragment = new DataFragment();
            fm.beginTransaction().add(dataFragment, “data”).commit();
            // load the data from the web
            dataFragment.setData(loadMyData());
        }

        // the data is available in dataFragment.getData()
        ...
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // store the data in the fragment
        dataFragment.setData(collectMyLoadedData());
    }
}
           

在上面的例子中,

onCreate()

中添加一個fragment(同時儲存activity的狀态對象)或者恢複fragment裡的資料。

onDestroy()

中更新fragment儲存的狀态對象。

自己處理配置改變

若在某些特定的配置變化下,不需要更新資料的話,我們可以避免activity重新啟動,那麼我們可以聲明activity将自己處理配置變化,阻止系統重新啟動。

注意:自行處理配置改變的話将會非常複雜,系統不會為我們自動處理(但是UI狀态不會被銷毀,仍然顯示)。這種方法應該是最後的選擇,在大多數應用中不推薦使用。

為了聲明activity處理配置改變,需要在manifest檔案中的

<activity>

中添加

<android:configChanges>

屬性,值表示我們處理哪些配置改變。最常用的兩個是:

orientation

keyboardHidden

。前者在螢幕方向變化時阻止重新開機,後者在鍵盤改變時阻止重新開機。可以通過

|

設定多個值。例如:

<activity android:name=".MyActivity"
          android:configChanges="orientation|keyboardHidden"
          android:label="@string/app_name">
           

當設定的配置發生變化時,activity不會重新啟動,而是調用`onConfigurationChanged(),該方法接收一個Configuration對象,用于指明新的配置,具體配置可以參考Configuration類。在調用該方法時,activity的資源對象自動更新來适應新的配置,是以我們很容易重新設定UI狀态。

自android3.2(API13)開始,橫豎屏切換也會導緻螢幕大小改變。是以若想在螢幕發生變化時阻止重新開機,在

<android:configChanges>

不僅需要添加

orientation

,還需要添加

screenSize

下面的例子實作了在配置發生變化時檢查目前的裝置方向:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
    }
}
           

在activity可以調用

this.getResources().getConfiguration()

擷取Configuration對象。Configuration成員變量的值都是static final int型,是以可以直接使用類調用。

大部分時候,我們不需要知道具體的配置變化,隻要重新處理資源(對于該配置能夠提供相應的選擇)即可。例如,在資源更新時,我們可以通過

setImageResoutce()

設定任何ImageViews,适應新的配置的資源就會自動使用。例如系統在layout-land和layout-port(在res目錄下建立layout-land(橫屏的layout)和layout-port(豎屏的layout)目錄,相應的layout檔案不變)目錄下自動尋找合适布局。

當activity處理配置變化時,我們應該重新設定每一個UI控件(及不同的配置顯示不同的布局),例如對于圖檔來說,要橫豎屏改變。

協調activities

當一個activity啟動另一個時,它們都經過了生命周期的切換。它們之間的切換時機是固定的,特别是在同一個程序中進行切換。下面是activity A切換到activity B的過程:

  1. A調用

    onPause()

  2. B依次調用

    onCreate()

    ,

    onStart()

    onResume()

    ,現在B獲得使用者焦點;
  3. 若A不再可見則調用

    onStop()

這種可以預測的執行順序可以友善我們管理activity切換之間的資訊。

以視窗Dialog形式顯示Activity

若要以視窗Dialog形式顯示Activity則需在AndroidMainfast.xml檔案的activity标簽中添加

android:theme

屬性。