官术网_书友最值得收藏!

3.2 Activity

Activity是Andorid組件中最基本也是最為常見的組件。Activity是用戶接口程序,原則上它會提供給用戶一個交互式的接口功能,幾乎所有的Activity都要和用戶打交道,也有人把它比喻成Android的管理員。需要在屏幕上顯示什么,用戶在屏幕上做什么,處理用戶不同操作等都由Activity來管理和調(diào)度。

Activity提供用戶與Android系統(tǒng)交互的接口,用戶通過Activity來完成自己的目的,例如打電話、拍照、發(fā)送E-mail、查看地圖等。每個Activity都提供一個用戶界面窗口,一般情況下,該界面窗口會填滿整個屏幕,但是也可以比屏幕小,或者浮在其他的窗口之上。

一個Android應(yīng)用程序通常由多個Activity組成,但是其中只有一個為主Activity,其作用相當(dāng)于Java應(yīng)用程序中的main函數(shù),當(dāng)應(yīng)用程序啟動時,作為應(yīng)用程序的入口首先呈現(xiàn)給用戶。Android應(yīng)用程序中的多個Activity直接可以相互調(diào)用以完成不同的工作。當(dāng)新的Activity被啟動的時候,之前的Activity會被停止,但是不會被銷毀,而是被壓入到“后退棧(Back Stack)”的棧頂,而新啟動的Activity獲得焦點,顯示給用戶。“后退棧”遵循“后入先出”的原則。當(dāng)新啟動的Activity被使用完畢,用戶單擊“Back”按鈕時,當(dāng)前的Activity會被銷毀,而原先的Activity會被從“后退棧”的棧頂彈出并且激活。

當(dāng)Activity狀態(tài)發(fā)生改變時,都會通過狀態(tài)回調(diào)函數(shù)通知Android系統(tǒng)。而程序編寫人員可以通過這些回調(diào)函數(shù)對Activity進行進一步的控制。

下面對Activity生命周期及其涉及的回調(diào)函數(shù)進行簡單介紹。

3.2.1 Activity的生命周期

從本質(zhì)上講,Activity在生命周期中共存在三個狀態(tài),分別為:


●運行態(tài):運行態(tài)指Activity運行于屏幕的最上層并且獲得了用戶焦點。

●暫停態(tài):暫停態(tài)是指當(dāng)前Activity依然存在,但是沒有獲得用戶焦點。在其之上有其他的Activity處于運行態(tài),但是由于處于運行態(tài)的Activity沒有遮擋住整個屏幕,當(dāng)前Activity有一部分視圖可以被用戶看見。處于暫停態(tài)的Activity保留了自己所使用的內(nèi)存和用戶信息,但是在當(dāng)系統(tǒng)極度缺乏資源的情況下,有可能會被殺死以釋放資源。

●停止態(tài):停止態(tài)是指當(dāng)前Activity完全被處于運行態(tài)的Activity遮擋住,其用戶界面完全不能被用戶看見。處于停止態(tài)的Activity依然存活,也保留了自己所使用的內(nèi)存和用戶信息,但是一旦系統(tǒng)缺乏資源,停止態(tài)的Activity就會被殺死以釋放資源。


Activity在聲明周期中從一種狀態(tài)到另一種狀態(tài)時會激發(fā)相應(yīng)的回調(diào)方法,這些回調(diào)方法包括:


●onCreate(Bundle savedInstanceState)。創(chuàng)建activity時調(diào)用。設(shè)置在該方法中,還以Bundle的形式提供對以前儲存的任何狀態(tài)的訪問。其中參數(shù)savedInstanceState對象是用于保存Activity的對象的狀態(tài)。

●onStart()。activity變?yōu)樵谄聊簧蠈τ脩艨梢姇r調(diào)用。

●onResume()。Activity開始與用戶交互時調(diào)用(無論是啟動還是重啟一個活動,該方法總是被調(diào)用的)。

●onPause()。當(dāng)Android系統(tǒng)要激活其他Activity時,該方法被調(diào)用,暫停或收回CPU和其他資源時調(diào)用。

●onStop()。Activity被停止并轉(zhuǎn)為不可見階段時調(diào)用。

●onRestart()。重新啟動已經(jīng)停止的Activity時調(diào)用。

●onDestroy()。Activity被完全從系統(tǒng)內(nèi)存中移除時調(diào)用,該方法被調(diào)用可能是因為有人直接調(diào)用finish()方法或者系統(tǒng)決定停止該活動以釋放資源。


上面7個生命周期方法分別在4個階段按照一定的順序進行調(diào)用,這4個階段如下:


●啟動Activity。在這個階段依次執(zhí)行3個生命周期方法:onCreate、onStart和onResume。

●Activity失去焦點。如果在Activity獲得焦點的情況下進入其他的Activity或應(yīng)用程序,這時當(dāng)前的Activity會失去焦點。在這一階段,會依次執(zhí)行onPause和onStop方法。

●Activity重獲焦點。如果Activity重新獲得焦點,會依次執(zhí)行3個生命周期方法:onRestart、onStart和onResume。

●關(guān)閉Activity。當(dāng)Activity被關(guān)閉時系統(tǒng)會依次執(zhí)行3個生命周期方法:onPause、onStop和onDestroy。


Activity生命周期中方法調(diào)用過程如圖3.1所示。

圖3.1 Activity生命周期

通過圖3.1,可以很直觀了解到activity的整個生命過程。Activity的生命過程表現(xiàn)在三個層面,如圖3.2所示。

圖3.2 Activity的整個生命周期

通過圖3.2可以更清楚地了解Activity的運行機制。如果Activity離開了可見階段,長時間失去了焦點,Activity就很可能被系統(tǒng)銷毀以釋放資源。當(dāng)然,即使該Activity被銷毀掉,用戶對該Activity所做的更改也會被保存在Bundle對象中,當(dāng)用戶需要重新顯示該Activity時,Android系統(tǒng)會根據(jù)之前保存的用戶更改信息將該Activity重建。

3.2.2 Activity的創(chuàng)建

在一個Android工程中,創(chuàng)建Activity的步驟如下:

步驟01 新建類。創(chuàng)建一個Activity,必須創(chuàng)建Android.app.Activity(或者它的一個已經(jīng)存在的子類)的一個子類,并重寫onCreate()方法。

步驟02 關(guān)聯(lián)布局xml文件。在新建的Activity中設(shè)置其布局方式,需要在res/layout目錄中新建一個xml布局文件,可以通過setContentView()來指定Activity的用戶界面的布局文件。

步驟03 注冊。在AndroidManifest.xml文件中對建立的Activity進行注冊,即在<application>標(biāo)簽下添加<activity>標(biāo)簽。例如,注冊ExampleActivity的代碼如下:

    <application ...>
         <activity Android:name=".ExampleActivity" />
          ...
    </application ...>

對于主Activity,要為其添加<intent-filter>標(biāo)簽。代碼如下:

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

其中<action Android:name="Android.intent.action.MAIN" />表示該Activity作為主Activity出現(xiàn),而<category Android:name="Android.intent.category.LAUNCHER" />表示該Activity會被顯示在最上層的啟動列表中。

3.2.3 啟動Activity

在Android系統(tǒng)中,除主Activity由系統(tǒng)啟動,其他Activity都要由應(yīng)用程序來啟動。

(1)通常情況下,通過startActivity()方法來啟動Activity,而要啟動的Activity的信息由Intent對象來傳遞。例如:

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

表示通過當(dāng)前的Activity啟動名為AnotherActivity的Activity。

有時,用戶不需要知道要啟動的Activity的名字,而可以僅制定要完成的行為,由Android系統(tǒng)來為用戶挑選合適的Activity。例如:

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

其中Intent.EXTRA_EMAIL放置的是recipientArray中存儲的要發(fā)送的E-mail的目標(biāo)地址。該Intent對象被startActivity()啟動后,Android系統(tǒng)會啟動相應(yīng)的E-mail處理應(yīng)用程序,并將Intent.EXTRA_EMAIL中的內(nèi)容放置到郵件的目標(biāo)地址中。

(2)有時,當(dāng)需要從啟動的Activity獲取返回值的時候,需要使用startActivityForResult()方法代替startActivity()方法,并實現(xiàn)onActivityResult()方法來獲取返回值。

例如,在發(fā)送短信的時候,用戶需要從聯(lián)系人列表中獲取聯(lián)系人的信息,然后返回到短信發(fā)送界面。代碼如下:

    Intent intent=new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
    startActivityForResult(intent, PICK_CONTACT_REQUEST);

當(dāng)用戶選擇了聯(lián)系人后,相關(guān)信息會被存儲到Intent對象中,并返回到onActivityResult()方法中。

3.2.4 關(guān)閉Activity

關(guān)閉Activity使用finish()方法。關(guān)閉之前啟動的其他Activity可以使用finishActivity()方法。

需要注意的是,雖然Android SDK提供了關(guān)閉Activity的方法,但是通常情況下,程序員不應(yīng)該使用這些方法去強制關(guān)閉Activity。因為Android系統(tǒng)在為用戶維護Activity的生命周期,并且提供了完備的資源回收機制和資源重建機制,可以動態(tài)地回收和重建Activity,因此Activity應(yīng)用交由Android系統(tǒng)來管理,除非已確定用戶不再需要當(dāng)前的Activity,并且不允許用戶回退到當(dāng)前Activity。

3.2.5 Activity數(shù)據(jù)傳遞

Activity數(shù)據(jù)傳遞共有三種:


●通過intent傳遞一些簡單的數(shù)據(jù)。

●通過Bundle傳遞相對復(fù)雜的數(shù)據(jù)或者對象。

●通過startActivityForResult可以更方便地進行來回的傳遞,當(dāng)然前兩種方法也可以來回傳遞。


假設(shè)由Activity1向Activity2傳遞數(shù)據(jù),利用三種方式實現(xiàn)的實例代碼如下。

(1)利用Intent傳遞數(shù)據(jù)。

在傳遞數(shù)據(jù)的Activity1中:

    Intent intent=new Intent(Activity1.this,Activity2.class);
    intent.putExtra("author","leebo");//在Intent中加入鍵值對數(shù)據(jù),鍵為“author”,值為“l(fā)eebo”
    Activity1.this.startActivity(intent);

在取出數(shù)據(jù)的Activity2中:

    Intent intent=getIntent();//獲得傳過來的Intent。
    String value=intent.getStringExtra("author");
    //根據(jù)鍵名author取出對應(yīng)鍵值為“l(fā)eebo”

(2)利用Bundle傳遞數(shù)據(jù)。

在傳遞數(shù)據(jù)的Activity1中:

    Intent intent=new Intent(Activity1.this,Activity2.class);
    Bundle myBundle=new Bundle();
    myBundle.putString("author","leebo");
    intent.putExtras(myBundle);
    Activity1.this.startActivity(intent);

在取出數(shù)據(jù)的Activity2中:

    Intent intent=getIntent();
    Bundle myBundle=intent.getExtras();
    String value=myBundle.getString("author"); //根據(jù)鍵名author取出對應(yīng)鍵值為“l(fā)eebo”

(3)利用startActivityForResult()傳遞數(shù)據(jù)。

startActivityForResult()方法不但可以把數(shù)據(jù)從Activity1傳遞給Activity2,還可以把數(shù)據(jù)從Activity2傳回給Activity1。

在Activity1中:

    final int REQUEST_CODE=1;
    Intent intent=new Intent(Activity1.this,Activity2.class);
    Bundle mybundle=new Bundle();
    mybundle.putString("author", "leebo");//把數(shù)據(jù)傳過去
    intent.putExtras(mybundle);
    startActivityForResult(intent, REQUEST_CODE);

重載onActivityResult方法,用來接收傳過來的數(shù)據(jù)(接收b中傳過來的數(shù)據(jù)):

    protected void onActivityResult(int requestCode, int resultCode,Intent intent){
    if(requestCode==this.REQUEST_CODE){
       switch(resultCode){
       case RESULT_OK:
          Bundle b=intent.getExtras();
          String str=b.getString("Result"); //獲取到Result中的值,為“from Activity2”
           break;
      default:
            break;
      }
      }
    }

在Activity2中:

    Intent intent=getIntent();
    Bundle myBundle=getIntent().getExtras();
    String author=getBundle.getString("author");
    Intent intent=new Intent();
    Bundle bundle=new Bundle();
    bundle.putString("Result","from Activity2");
    intent.putExtras(bundle);

Activity02.this.setResult(RESULT_OK,intent);//通過intent將數(shù)據(jù)返回給Activity1,RESULT_ OK是結(jié)果碼:

    finish();//結(jié)束當(dāng)前的Activity。

本質(zhì)上,這三種數(shù)據(jù)傳遞方式都是通過Intent來完成的。

主站蜘蛛池模板: 拜城县| 南和县| 凤台县| 德令哈市| 会昌县| 肥西县| 彰化县| 自贡市| 南通市| 凭祥市| 本溪市| 黄山市| 梅河口市| 昔阳县| 萍乡市| 云阳县| 梧州市| 扶余县| 福安市| 长泰县| 泰宁县| 寿阳县| 盈江县| 泗水县| 柳林县| 高平市| 扎鲁特旗| 盐山县| 晴隆县| 广河县| 徐汇区| 上饶县| 内乡县| 水富县| 门源| 滕州市| 聂荣县| 通河县| 阿坝| 肇东市| 井冈山市|