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

3.2 Activity

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

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

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

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

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

3.2.1 Activity的生命周期

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


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

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

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


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


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

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

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

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

●onStop()。Activity被停止并轉為不可見階段時調用。

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

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


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


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

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

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

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


Activity生命周期中方法調用過程如圖3.1所示。

圖3.1 Activity生命周期

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

圖3.2 Activity的整個生命周期

通過圖3.2可以更清楚地了解Activity的運行機制。如果Activity離開了可見階段,長時間失去了焦點,Activity就很可能被系統(tǒng)銷毀以釋放資源。當然,即使該Activity被銷毀掉,用戶對該Activity所做的更改也會被保存在Bundle對象中,當用戶需要重新顯示該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 關聯(lián)布局xml文件。在新建的Activity中設置其布局方式,需要在res/layout目錄中新建一個xml布局文件,可以通過setContentView()來指定Activity的用戶界面的布局文件。

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

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

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

    <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都要由應用程序來啟動。

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

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

表示通過當前的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的目標地址。該Intent對象被startActivity()啟動后,Android系統(tǒng)會啟動相應的E-mail處理應用程序,并將Intent.EXTRA_EMAIL中的內容放置到郵件的目標地址中。

(2)有時,當需要從啟動的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);

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

3.2.4 關閉Activity

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

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

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

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


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

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

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


假設由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取出對應鍵值為“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取出對應鍵值為“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是結果碼:

    finish();//結束當前的Activity。

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

主站蜘蛛池模板: 仙居县| 玉林市| 沿河| 鄂尔多斯市| 诏安县| 乌鲁木齐市| 彩票| 盐津县| 嘉禾县| 安庆市| 汾西县| 苍溪县| 黄陵县| 绥棱县| 景东| 无棣县| 甘泉县| 沂源县| 百色市| 云梦县| 泸定县| 光山县| 龙游县| 宁晋县| 石首市| 贺兰县| 乌什县| 会昌县| 富蕴县| 绥芬河市| 达尔| 福州市| 清水县| 庆安县| 松滋市| 盐源县| 海安县| 乐安县| 桦川县| 怀远县| 神池县|