Android Activity詳解
Activity是Android系統(tǒng)中的四大組件之一众弓,用于顯示View谓娃,與用戶(hù)交互滨达。
Activity的生命周期
Activity的生命周期為:
protected void onCreate(Bundle savedInstanceState);
protected void onStart();
protected void onRestart();
protected void onResume();
protected void onPause();
protected void onStop();
protected void onDestroy();
1.啟動(dòng)Activity:系統(tǒng)會(huì)先調(diào)用onCreate
方法,然后調(diào)用onStart
方法,最后調(diào)用onResume
涩搓,Activity進(jìn)入運(yùn)行狀態(tài)。
2.當(dāng)前Activity被其他Activity覆蓋其上或被鎖屏:系統(tǒng)會(huì)調(diào)用onPause
方法充边,暫停當(dāng)前Activity的執(zhí)行浇冰。
3.當(dāng)前Activity由被覆蓋狀態(tài)回到前臺(tái)或解鎖屏:系統(tǒng)會(huì)調(diào)用onResume
方法,再次進(jìn)入運(yùn)行狀態(tài)漂佩。
4.當(dāng)前Activity轉(zhuǎn)到新的Activity界面或按Home鍵回到主屏,自身退居后臺(tái):系統(tǒng)會(huì)先調(diào)用onPause
方法,然后調(diào)用onStop
方法关拒,進(jìn)入停滯狀態(tài)夏醉。
5.用戶(hù)后退回到此Activity:系統(tǒng)會(huì)先調(diào)用onRestart
方法畔柔,然后調(diào)用onStart
方法靶擦,最后調(diào)用onResume
方法,再次進(jìn)入運(yùn)行狀態(tài)枚粘。
6.當(dāng)前Activity處于被覆蓋狀態(tài)或者后臺(tái)不可見(jiàn)狀態(tài)馍迄,即第2步和第4步攀圈,系統(tǒng)內(nèi)存不足,殺死當(dāng)前Activity凯傲,而后用戶(hù)退回當(dāng)前Activity:再次調(diào)用onCreate
方法忧风、onStart
方法狮腿、onResume
方法缘厢,進(jìn)入運(yùn)行狀態(tài)椿每。
7.用戶(hù)退出當(dāng)前Activity:系統(tǒng)先調(diào)用onPause
方法间护,然后調(diào)用onStop
方法汁尺,最后調(diào)用onDestory
方法,結(jié)束當(dāng)前Activity狼荞。
狀態(tài)保存:
onSaveInstanceState():
如果沒(méi)有覆寫(xiě)onSaveInstanceState()
方法, 它的默認(rèn)實(shí)現(xiàn)會(huì)自動(dòng)保存activity中的某些狀態(tài)數(shù)據(jù),拾积。比如activity中UI控件殷勘,EditText控件會(huì)自動(dòng)保存和恢復(fù)輸入的數(shù)據(jù)摘符;CheckBox控件會(huì)自動(dòng)保存和恢復(fù)選中狀態(tài)逛裤。只需要為這些控件設(shè)置android:id屬性即可, 剩余的事情就可以自動(dòng)完成了带族。如果沒(méi)有為控件設(shè)定ID, 則這個(gè)控件就不會(huì)進(jìn)行自動(dòng)的數(shù)據(jù)保存和恢復(fù)阳堕。
什么時(shí)候使用:
如:屏幕的方向發(fā)生了改變恬总, Activity會(huì)被摧毀并且被重新創(chuàng)建壹堰,如果你想在Activity被重新創(chuàng)建后恢復(fù)緩存的數(shù)據(jù)∽缓福可以重寫(xiě)Activity的 onSaveInstanceState()
和 onRestoreInstanceState()
方法懊渡。
@Override
public void onSaveInstanceState(Bundle savedInstanceState){
//調(diào)用父類(lèi)
super.onSaveInstanceState(savedInstanceState);
//存儲(chǔ)自己的數(shù)據(jù)
savedInstanceState.putString("message", text.getText().toString());
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState){
super.onRestoreInstanceState(savedInstanceState);
//取出數(shù)據(jù)
message = savedInstanceState.getString("message");
}
Activity的4種啟動(dòng)模式
當(dāng)應(yīng)用運(yùn)行起來(lái)后就會(huì)開(kāi)啟一條線程,線程中會(huì)運(yùn)行一個(gè)任務(wù)棧肾档,當(dāng)Activity實(shí)例創(chuàng)建后就會(huì)放入任務(wù)棧中,啟動(dòng)模式簡(jiǎn)單地說(shuō)就是Activity啟動(dòng)時(shí)的策略遣耍。在AndroidManifest.xml中的標(biāo)簽的android:launchMode屬性設(shè)置或者在Intent中設(shè)置flag舵变。
啟動(dòng)模式有4種
standard模式(默認(rèn)):
每次啟動(dòng)Activity時(shí),都創(chuàng)建Activity實(shí)例绵咱,并放入任務(wù)棧悲伶。
singleTop模式:
在任務(wù)的棧頂存在該Activity的實(shí)例蒂萎,會(huì)調(diào)用實(shí)例的
onNewIntent()
,就重用該實(shí)例泻拦,否者就會(huì)創(chuàng)建新的實(shí)例并放入棧頂(即使棧中已經(jīng)存在該Activity實(shí)例争拐,只要不在棧頂架曹,都會(huì)創(chuàng)建實(shí)例)。
singleTask模式:
在棧中已經(jīng)有該Activity的實(shí)例万牺,會(huì)調(diào)用實(shí)例的
onNewIntent()
,重用該實(shí)例核无。重用時(shí)团南,會(huì)讓該實(shí)例回到棧頂,在它上面的實(shí)例將會(huì)被移除棧。如果棧中不存在該實(shí)例朋腋,將會(huì)創(chuàng)建新的實(shí)例放入棧中齐疙。
singleInstance模式:
在一個(gè)新棧中創(chuàng)建該Activity實(shí)例膜楷,并讓多個(gè)應(yīng)用共享改棧中的該Activity實(shí)例。如果應(yīng)用1的任務(wù)棧中創(chuàng)建了MainActivity實(shí)例贞奋,應(yīng)用2也要啟動(dòng)MainActivity赌厅,則不需要?jiǎng)?chuàng)建,兩應(yīng)用共享該Activity實(shí)例轿塔。
調(diào)用onNewIntent():
當(dāng)singleTop singleTask singleInstance模式下重用實(shí)例時(shí)會(huì)調(diào)用onNewIntent()
可以在改方法中更新intent數(shù)據(jù)。
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
//更新intent數(shù)據(jù)
setIntent(intent);
//處理其它數(shù)據(jù)
processData();
}
Activity 之間通信
第一個(gè)啟動(dòng)的Activity需要在AndroidManifest.xml里面聲明:
<activity
android:name=".StartActivity">
<intent-filter>
//應(yīng)用程序最先啟動(dòng)的Activity
<action android:name="android.intent.action.MAIN" />
/應(yīng)用程序是否顯示在程序列表里
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Intent使用:
Intent是一個(gè)消息傳遞對(duì)象兜畸,可以用來(lái)啟動(dòng)Activity痘系、Service和Broadcast,將 Intent 傳遞給 startActivity()
佛纫,可以啟動(dòng)新的 Activity 實(shí)例;通過(guò)將 Intent 傳遞給 startService()
,可以啟動(dòng)服務(wù);將 Intent 傳遞給 sendBroadcast()
、sendOrderedBroadcast()
或 sendStickyBroadcast()
,可以發(fā)送廣播笋熬。
Intent類(lèi)型:
Intent分為兩種類(lèi)型:顯式Intent和隱式Intent糖耸。
顯式Intent:
按名稱(chēng)(全類(lèi)名)指定要啟動(dòng)的組件舍扰。
如:
Intent intent = new Intent(Activity1.this , Activity2.class);
//可以攜帶一些值
Bundle bundle = new Bundle();
bundle.putString("username",username);
//放入intent中
intent.putExtras(bundle);
startActivity(intent)
在Activity2.class中接收
Intent intent = getIntent();
//獲取Bundle
Bundle bundle = intent.getExtras();
//通過(guò)key取值
String name = bundle.getString("username");
隱式Intent:
不會(huì)指定特定的組件个束,而是聲明要執(zhí)行的常規(guī)操作殿如,從而允許其他應(yīng)用中的組件來(lái)處理它谨胞。
首先是在AndroidManifest.xml中為某個(gè)Activity設(shè)置意圖過(guò)濾器:
<activity>
<intent-filter>
<action android:name="...."/>
<category android:name="...."/>
<!--聲明隱式意圖-->
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="..." android:host="..." android:path="/..." android:type="..."/>
</intent-filter>
</activity>
在程序中要設(shè)置的是我們要尋找時(shí)匹配的條件
Intent intent = new Intent();
intent.setAction("....");
intent.addCategory("....");
//設(shè)置data的scheme忘朝、host肴茄、path條件
intent.setData(Uri.parse("...."));
//設(shè)置data的scheme拦坠、host疲迂、path腰池、type條件
intent.setDataAndType(Uri.parse(""),String type);
startActivity(intent);
URI的格式<scheme>://<host>:<port>[<path>|<pathPrefix>|<pathPattern>]