您好,登錄后才能下訂單哦!
Activity 是我們在學習android 的時候最先接觸到的東西,也是android 開發過程中不可少的組件。而 在我們android 學習中,對activity 有個全面的認識是很重要的。本人在學習android 以來,對activity 也是又愛又恨,所以特意做了個總結,希望能對 那些 activity 認識還不夠的“同鞋”一些幫助。
內容提要
1、Activity 的概念
2、Activity 類繼承關系
3、Activity 的生命周期
4、Activity 橫豎屏切換時生命周期變化
5、Activity 啟動模式
6、Activity 之間通信數據傳遞
7、Activity 的回收與數據保存
內容詳情
1、Activity 的概念
在谷歌給的官方Android Api文檔中,是這么描述 Activity中的:
一個 activity 是一個單一的,聚焦了用戶可以做的事情。幾乎所有的 activity 都與用戶進行交互,因此 activity 需要關注創建一個窗口,可以通過 setContentView(int) 來更新替換 UI 視圖界面。activity 往往是以全屏方式呈現給用戶的,你也可以通過設置主題或將activity嵌入其他activity 的方式來改變。
2、Activity 類繼承關系
通過這張類圖,我們可以看到,activity 是繼承于 ContenttextThemeWrapper 類的,是它的直接也是唯一子類。
而activity 的直接子類 則有ActivityGroup、AliasActiviyt、ExpandableListActivity和 ListActivity,其中常用的有 ListActivity (后面再講List 相關用法時,會講下ListActivity的相關用法)。
3、Activity 的生命周期
相信這張圖你已經見過很多次了吧,經典永遠是值得學習的。下面我們就來好好學習下經典。
所有的 activity 都會實現兩個方法:onCreate() 和 onPause()方法。
下面就來具體講講圖中的各個方法詳情和都在什么情況下調用:
onCreate: 在這里創建界面,做一些數據的初始化工作
onStart: 到這一步變成用戶可見不可交互的
onResume: 變成和用戶可交互的,(在activity 棧系統通過棧的方式管理這些個Activity的最上面,運行完彈出棧,則回到上一個Activity)
onPause: 到這一步是可見但不可交互的,系統會停止動畫等消耗CPU 的事情從上文的描述已經知道,應該在這里保存你的一些數據,因為這個時候你的程序的優先級降低,有可能被系統收回。在這里保存的數據,應該在onResume里讀出來,注意:這個方法里做的事情時間要短,因為下一個activity不會等到這個方法完成才啟動
onstop: 變得不可見,被下一個activity覆蓋了
onDestroy: 這是activity被干掉前最后一個被調用方法了,可能是外面類調用finish方 法或者是系統為了節省空間將它暫時性的干掉,可以用isFinishing()來判斷它,如果你有一個ProgressDialog在線程中轉動,請在onDestroy里把他cancel掉,不然等線程結束的時候,調用Dialog的cancel方法會拋異常的。
注:onPause,onstop, onDestroy,三種狀態下 activity都有可能被系統干掉。
正常啟動activity:onCreate-> onStart -> onResume(啟動)
正常退出activity: (啟動)-> onPause-> onStop -> onDestroy(退出)
activity 啟動后被打斷,進入一個新全屏activity:
(啟動)-> onPause->onStop
恢復時:onStart->onResume
activity 啟動后被打斷,進入一個不是全屏的窗口,如Dialog之類的:
(啟動)-> onPause
恢復時:onResume
4、Activity 橫豎屏切換時生命周期變化
在android 程序清單中聲明activity 時我們可以設置 activity在橫豎屏切換時的生命周期變化,具體情況如下:
不設置Activity的android:configChanges時,切屏會重新調用各個生命周期,切橫屏時會執行一次,切豎屏時會執行兩次。
設置Activity的android:configChanges="orientation"時,切橫,豎屏時生命周期只會執行一次。
設置Activity的android:configChanges="orientation|keyboardHidden"時,切屏不會重新調用聲明周期,只會執行onConfigurationChanged方法。
5、Activity 啟動模式
我們知道在繼承一個activity類時,當我們要將自己寫的 activity啟動的時候,我們需要在 androidManifest.xml 程序清單里面,聲明所要啟動的 activity,而在聲明 activity 的同時 我們可以設置activity 的啟動模式,launchModel = "...",在android 系統中 ,activity 有四種啟動模式,而系統默認是 standard,啟動模式在某些需求的情況下可以方便系統 對activity 的管理。
下面說解講下四種啟動模式的各自的特點和區別:
standard:
默認模式,可以不用寫配置。
activity在同一個任務棧,
每啟動一個activity,都會默認創建一個新的實例。
因此,在這種模式下,可以有多個相同的實例,也允許多個相同Activity疊加。
singleTop:
activity在同一個任務棧,
當要啟動的activity處于棧頂時,重復啟動之前已創建的實例;
當要啟動的activity 不處于棧頂時,會創建新的實例
singleTask:
activity在同一個任務棧,只在一個實例,若創建了將不重復創建;
在啟動已在棧里面有的activity時(由棧頂的activity(B) 跳轉到下面的 activity (A)時),會將在A上面的activity 一直彈出,一直到A。
singleInstance:
每個activity是獨立任務棧,且只放一個activity實例, activity的之間的切換會在幾個不同任務棧之間跳轉。
6、Activity 之間通信數據傳遞
在平常的android 開發過程中, 很多活動界面之前是需要傳遞數據的,也就是說在activity之間是需要傳遞數據,而數據怎么傳遞,傳遞什么樣的數據,這些都要有一定的了解。
下面詳細介紹:
1、簡單數據采用 Intent 來傳遞
A->B
A中 綁定數據:
Intent intent = new Intent( this, MyReceiver.class);
intent.putExtra( "data", "data from A");
StartActivity(intent);
B中 接收數據:
String data = intent.getStringExtra( "data");
2、數據包采用Bunde 來傳遞
A->B
A中 綁定數據:
Bundle b = new Bundle();
b.putString("string","String data from A");
b.putInt("int","Int data from A");
b.putBoolean("boolean","Boolean data from A");
Intent intent = new Intent( this, MyReceiver.class);
intent.putExtra("datas",b);//intent.putExtra(b);
B中接收數據:
Bundle b = getIntent.getExtras("datas")//b = getIntent().getExtras();
String datastr = b.getString("string","default");//default為缺省值
3、對象的傳遞
A->B ,class User (name,age)
1》Serializable java語言提供 ,效率較低
User中:繼承Serializable , class User implements Serializable
A中: intent.putExtra("user",new User());
B中: User user = (User)getIntent().getSerializableExtra("user");
2》Parcelable 專門面向移動端,效率較高
User中:繼承Parcelabe , class User implements Parcelable
實現兩方法:
public int describeContents(){return 0}
public void writeToParcel(Parcel dest, int flags){
dest.writeBundle()//這樣可以傳遞很多相同類型數據了
dest.writeString(getName());
dest.writeInt(getAge());
}
public static final Creator<User> CREATOR = new Creator<User>(){
public User createFromParcel(Parcel source){
source.readBundle();//
return new User(source.readString(),source.readInt());
}
public User[] newArray(int size){
return new User[size ];
}
}
A中: intent.putExtra("user",new User());
B中: User user = (User)getIntent().getParcelableExtra("user");
3、從被啟動的activity 傳遞數據到 主activity(返回傳遞數據)
A->B,B->A
B中:返回時監聽:
String bData;
Intent intent = new Intent();
intent.putExtra("dataB",bData );
setResult(1,intent);//返回狀態碼可以自行設定
finish();
A中:在啟動時:
startActivityForResult(intent, 0);//返回的請求碼
實現方法:onActivityResult(int requestCode,int resultCode,Intent data)
onActivityResult(int requestCode,int resultCode,Intent data){
if(requestCode == 0){
if(resultCode == 1)
String s = data.getStrignExtra("dataB");
}
}
4、還有一種懶漢方法來傳遞數據,進行通信如設置一個公共類,在公共類中,將要傳遞的數據聲明為 公有靜態的(public static ),這樣就可以在直接在activity之間進行通信了。當然這種數據也可以放在 application 這個全局的 類里面。這種方法通常是用來判斷 是否登陸超時,或是一些全局的配置等等。
7、Activity 的回收與數據保存
之前在講解 activity 生命周期的時候,我們就已經知道了,activity 在某些情況下會被系統干掉的,如果這個activity 又在做一些重要的數據,舉一個簡單的例子, 我們在登錄一個時,只填寫了一部分,臨時離開了這個界面,當我們返回時,如果又需要重新在填寫全部的數據,這是不是有點坑,,,嚴重影響用戶體驗。
當然這只是舉的一個小例子,或許有點不恰當,但我們確實是需要在系統回收 activity ,activity被異常干掉的時候保存當前的用戶數據 ,而在再次打開或恢復時,應當能還原當初的數據。
因為 activity 的切換,所以當用戶在再次切換回原來的 activity的時候,原先的 activity 有兩種情況:一種是被回收,一種是沒有被回收,
被回收的A就要重新調用onCreate()方法,不同于直接啟動的是這回onCreate()里是帶上參數
savedInstanceState,沒被收回的就還是onResume就好了。
savedInstanceState是一個Bundle對象,你基本上可以把他理解為系統幫你維護的一個Map對象。在onCreate()里你可能會用到它,如果正常啟動onCreate就不會有它,所以用的時候要判斷一下是否為空。
前面在生命周期也講過,我們可以在onPause 方法中 保存數據,而在 onResume 方法中恢復數據。
其實谷歌早就考慮到了關于 activity 異常退出,被系統回收的 的 數據 保存與恢復相關的問題。
那就是這兩個方法: onSaveInstanceState(Bundle outState) 和 onRestoreInstanceState(Bundle savedInstanceState) 方法,這兩個 前者是負責在activity被異常干掉之前保存數據,而后者是負責恢復數據。
注:
onSaveInstanceState()方法,在正常情況下就不會被調用的,只有當 activity 發生異常時才會被調用。
onRestoreInstanceState()方法,系統會調用,其實也是不需要我們人為去干涉的。
我們接著看,注意 onSaveInstanceState(Bundle outState )方法的參數,是的,是 Bundle 類型的,還記得前面提到過的 數據傳遞部分嗎,Bundld 就可以保存大多數的數據。 現在或許有人說 onRestoreInstanceState() 方法我們可以不去多管,總感覺心里不踏實,是吧,那我們在哪個地方 將 outState 里面保存的數據拿出來呢?
我們再看看 onCreate(Bundle savedInstanceState) ,是不是發現什么了,這個參數,也是Bundle 類型的,其實這里的 savedInstanceState 就是之前保存的 outState,而我們可以在onCreate 方法中取消之前 保存的數據。
最后問的歸納如下:
保存數據:
void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putLong("id",1234567890); }
判斷 和 恢復 數據:
void onCreate(Bundle savedInstanceState){ .......... if(savedInstanceState != null){ ..... } }
好了,到這里我們對 activity 已經有了個大概的理解了,而博客也到這里結束了。這是 本人 第一次寫的 關于 android 的文章 ,從自己學習android 以來,中間有苦有甜,有笑有淚,不容易啊,今天在我即將走出校園,即將用 android 來謀生的同時,寫下這篇博客,希望能在android這條路上走得越來越寬,越來越遠。
注:這博客是總結型的,中間有我自己對 android api 的翻譯,同樣其中不免有些知識點是有和其他文章有相通的,所以如果有失禮或者是有不是很恰當的地方,還請前輩們見諒。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。