- Android 5從入門到精通
- 李波
- 2730字
- 2021-03-19 15:29:00
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來完成的。
- Cocos2d Cross-Platform Game Development Cookbook(Second Edition)
- Learn ECMAScript(Second Edition)
- C語言程序設計實踐教程(第2版)
- Raspberry Pi for Python Programmers Cookbook(Second Edition)
- PWA入門與實踐
- Microsoft Exchange Server PowerShell Cookbook(Third Edition)
- 深入淺出Java虛擬機:JVM原理與實戰(zhàn)
- Python貝葉斯分析(第2版)
- The Complete Coding Interview Guide in Java
- Corona SDK Mobile Game Development:Beginner's Guide(Second Edition)
- UVM實戰(zhàn)
- HTML5 APP開發(fā)從入門到精通(微課精編版)
- Python圖形化編程(微課版)
- Learning Android Application Testing
- 深入解析Java編譯器:源碼剖析與實例詳解