Android學(xué)習(xí)(二)—— 四大組件之Activity

本文目錄結(jié)構(gòu):
一寺酪、活動(dòng)的生命周期
二输涕、活動(dòng)的啟動(dòng)模式
三盐数、活動(dòng)間的信息傳遞之一 —— Intent

一埂淮、活動(dòng)的生命周期

1.返回棧

Android是使用任務(wù)(Task)來管理活動(dòng)的姑隅,一個(gè)任務(wù)就是一組存放在棧里的活動(dòng)的集合,這個(gè)棧也叫返回棧倔撞。在默認(rèn)情況下讲仰,當(dāng)我們啟動(dòng)了一個(gè)活動(dòng),那么它會(huì)入棧误窖,并處于棧頂?shù)奈恢枚E獭.?dāng)我們按下返回鍵或者調(diào)用finish方法時(shí),處于棧頂?shù)幕顒?dòng)就會(huì)出棧霹俺。系統(tǒng)總是顯示處于棧頂?shù)幕顒?dòng)柔吼。

2.活動(dòng)狀態(tài)

活動(dòng)的狀態(tài)可以分為4種:
(1)運(yùn)行狀態(tài)
當(dāng)一個(gè)活動(dòng)處于棧頂?shù)臅r(shí)候,那么它就處于運(yùn)行狀態(tài)丙唧。系統(tǒng)就不愿意就是回收運(yùn)行狀態(tài)的活動(dòng)愈魏,因?yàn)檫@會(huì)給用戶帶來很不好的體驗(yàn)。
(2)暫停狀態(tài)
當(dāng)一個(gè)活動(dòng)不處于棧頂?shù)匀豢梢姇r(shí)想际,它就處于暫停狀態(tài)培漏。比如對(duì)話框形式的活動(dòng)只會(huì)占用屏幕中間的區(qū)域。系統(tǒng)也不愿意回收這樣的活動(dòng)胡本,只有在內(nèi)存極低的時(shí)候才會(huì)考慮去回收牌柄。
(3)停止?fàn)顟B(tài)
當(dāng)一個(gè)活動(dòng)不再處于棧頂,并且不可見的時(shí)候侧甫,就進(jìn)入了停止?fàn)顟B(tài)珊佣。系統(tǒng)仍然會(huì)為這種活動(dòng)保存相應(yīng)的狀態(tài)和成員變量,但這并不是完全可靠的披粟。當(dāng)其他地方需要內(nèi)存咒锻,系統(tǒng)就有可能回收掉該活動(dòng)。
(4)銷毀狀態(tài)
當(dāng)一個(gè)活動(dòng)被棧移除之后守屉,它就處于銷毀狀態(tài)惑艇。系統(tǒng)最愿意回收這樣的活動(dòng),從而保持手機(jī)內(nèi)存的充足拇泛。

3.活動(dòng)的生命周期

(1)onCreate
它會(huì)在活動(dòng)第一次創(chuàng)建的時(shí)候被調(diào)用滨巴。我們應(yīng)該在該方法中完成活動(dòng)的初始化操作,比如加載布局俺叭、綁定事件等恭取。
(2)onStart
該方法在活動(dòng)由不可見變?yōu)榭梢姷臅r(shí)候調(diào)用。
(3)onResume
該方法在活動(dòng)準(zhǔn)備好和用戶交互的時(shí)候調(diào)用绪颖。此時(shí)的活動(dòng)一定處于棧頂?shù)奈恢谩?br> (4)onPause
該方法在系統(tǒng)準(zhǔn)備去啟動(dòng)或恢復(fù)另一個(gè)活動(dòng)的時(shí)候調(diào)用秽荤。我們通常會(huì)在這個(gè)方法中將一些消耗CPU的資源釋放掉甜奄,但該方法的執(zhí)行速度一定要快,不然會(huì)影響到新的棧頂活動(dòng)的調(diào)用窃款。
(5)onStop
該方法在活動(dòng)完全不可見的時(shí)候調(diào)用课兄。它和onPause方法不同的是,如果啟動(dòng)的新活動(dòng)是一個(gè)對(duì)話框形式的活動(dòng)晨继,那么onPause方法會(huì)被調(diào)用烟阐,而它不會(huì)。
(6)onDestroy
該方法會(huì)在活動(dòng)被銷毀之前調(diào)用紊扬。
(7)onRestart
該方法會(huì)在活動(dòng)從停止?fàn)顟B(tài)變?yōu)檫\(yùn)行狀態(tài)之前調(diào)用蜒茄。

活動(dòng)的生命周期.jpg

PS:如果活動(dòng)被銷毀了,但是可能存在臨時(shí)數(shù)據(jù)和狀態(tài)餐屎,那要怎么辦呢檀葛?
①可以調(diào)用onSaveInstanceState方法將數(shù)據(jù)臨時(shí)保存起來
@Override
protected void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
String data = "Keep it";
outState.putString("tempData",data);
}
②然后在onCreate方法中判斷savedInstanceState是否為空
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
......
if(savedInstanceState != null)
String tempData = savedInstanceState.getString("tempData");
}

二、活動(dòng)的啟動(dòng)模式

活動(dòng)的啟動(dòng)模式一共有4種腹缩,它們需要在AndroidManifest文件中通過給<activity>標(biāo)簽指定android:launchMode屬性來設(shè)置屿聋。

1.standard

它是活動(dòng)默認(rèn)的啟動(dòng)模式。每當(dāng)有一個(gè)活動(dòng)啟動(dòng)時(shí)藏鹊,它就會(huì)入棧并處于棧頂?shù)奈恢萌蠹ァO到y(tǒng)根本不在乎棧里是否已經(jīng)有了該活動(dòng)的實(shí)例,每次啟動(dòng)活動(dòng)都會(huì)創(chuàng)建一個(gè)新的實(shí)例盘寡。


standard.jpg
2.singleTop

當(dāng)活動(dòng)指定為該模式時(shí)楚殿,在啟動(dòng)活動(dòng)時(shí)如果發(fā)現(xiàn)棧頂?shù)幕顒?dòng)已經(jīng)是該活動(dòng),則系統(tǒng)會(huì)直接使用它竿痰,不會(huì)再創(chuàng)建新的活動(dòng)實(shí)例脆粥。但如果該活動(dòng)不在棧頂時(shí)再啟動(dòng)該活動(dòng)時(shí),還是會(huì)創(chuàng)建新的實(shí)例的菇曲。


singleTop.jpg
3.singleTask

當(dāng)活動(dòng)處于該模式時(shí)冠绢,每次啟動(dòng)活動(dòng)時(shí)系統(tǒng)首先會(huì)在棧里檢查是否存在該活動(dòng)的實(shí)例抚吠,如果發(fā)現(xiàn)有則直接使用常潮,并把在該活動(dòng)之上的所有活動(dòng)出棧。如果沒發(fā)現(xiàn)則創(chuàng)建一個(gè)新的活動(dòng)實(shí)例楷力。


singleTask.jpg
4.singleInstance

當(dāng)活動(dòng)處于該模式時(shí)喊式,系統(tǒng)會(huì)啟用一個(gè)新的棧來管理這個(gè)活動(dòng)。它可以解決共享活動(dòng)實(shí)例的問題萧朝。比如:活動(dòng)B為該模式岔留,然后A啟動(dòng)B,B啟動(dòng)C检柬,那么第一次按下返回鍵時(shí)系統(tǒng)會(huì)回到A献联,再按下一次時(shí)會(huì)回到B,再按下一次則退出應(yīng)用。一個(gè)棧里的活動(dòng)沒有了之后才會(huì)去到另一個(gè)棧里逆。


singleInstance.png

三进胯、活動(dòng)間的信息傳遞之一 —— Intent

1.顯式Intent

(1)構(gòu)造方法

//Intent intent = new Intent(Context packageContext,Class<?> cls);
//前者為啟動(dòng)活動(dòng)的上下文,后者為想要啟動(dòng)的目標(biāo)活動(dòng)
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);

(2)setComponent方法

ComponentName componentName = new ComponentName(this, SecondActivity.class);  
Intent intent = new Intent();  
intent.setComponent(componentName);  
startActivity(intent);

(3)setClass/setClassName方法

Intent intent = new Intent();  
intent.setClass(this, SecondActivity.class);  
// 或者intent.setClassName(this, "top.longsh1z.www.SecondActivity");  
// 或者intent.setClassName(this.getPackageName(), "top.longsh1z.www.SecondActivity");        
startActivity(intent);
2.隱式Intent

顧名思義原押,隱式Intent不會(huì)明確的指出想要啟動(dòng)的activity胁镐,而是通過指定action和category等信息讓系統(tǒng)來選擇要啟動(dòng)的活動(dòng)。

首先诸衔,在AndroidManifest文件中盯漂,目標(biāo)活動(dòng)要有<intent-filter>標(biāo)簽,里面包含<action><category>子標(biāo)簽笨农,只有這兩個(gè)子標(biāo)簽中的內(nèi)容同時(shí)匹配才能夠生效就缆。比如:

<activity android:name=".ui.Main2Activity">
  <intent-filter>
    <action android:name="top.longsh1z.www.Main2Activity"/>
    <!--該category是一種默認(rèn)的category-->
    <!--在調(diào)用startActivity方法時(shí)會(huì)自動(dòng)將這個(gè)category加到intent中-->
    <category android:name="android.intent.category.DEFAULT"/>
  </intent-filter>
</activity>

設(shè)置intent有兩種方法:
(1)構(gòu)造方法

Intent intent = new Intent("top.longsh1z.www.Main2Activity");
//如果category不是默認(rèn)的話要再加下面的一條語句
//比如在AndroidManifest中自定義的category為
//top.longsh1z.www.Main2Activity_category,那么該語句為
//intent.addCategory("top.longsh1z.www.Main2Activity_category");
startActivity(intent);

(2)setAction方法

Intent intent = new Intent();
intent.setAction("top.longsh1z.www.Main2Activity");
//如果category不是默認(rèn)的話同上
startActivity(intent);
3.更多隱式Intent的用法

我們也可以調(diào)用系統(tǒng)中固有的活動(dòng)谒亦,比如系統(tǒng)的瀏覽器违崇,撥號(hào)等等。比如調(diào)用系統(tǒng)瀏覽器:

//Intent.ACTION_VIEW是系統(tǒng)內(nèi)置的動(dòng)作诊霹,其常量值為android.intent.action.VIEW
Intent intent = new Intent(Intent.ACTION_VIEW);
//這條語句的意思是打開百度羞延,具體其他用法請(qǐng)自己搜索
intent.setData(Uri.parse("https://www.baidu.com"));
startActivity(intent);

另外,在一個(gè)活動(dòng)的<action>標(biāo)簽里也可以寫成系統(tǒng)內(nèi)置的動(dòng)作脾还。當(dāng)然這個(gè)前提是你的程序要有這樣的功能伴箩,不然的話就會(huì)報(bào)錯(cuò)。

4.向下一個(gè)活動(dòng)傳遞數(shù)據(jù)

使用intent.putExtra方法放消息鄙漏,使用intent.getStringExtra方法拿消息嗤谚。

//放消息進(jìn)intent中
String data = "Hello world!";
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
intent.putExtra("MyData",data);
//其中data不一定只限于字符串,也可以為int,boolean類型
startActivity(intent);

//取消息
Intent intent = getIntent();
String data = intent.getStringExtra("MyData");
//若傳遞的數(shù)據(jù)為其他類型怔蚌,則為getXxxExtra方法巩步,比如getIntExtra,getBooleanExtra方法

5.返回?cái)?shù)據(jù)給上一個(gè)活動(dòng)
總體思路為(這里假設(shè)是FActivity<簡(jiǎn)寫為F>)跳到SActivity<簡(jiǎn)寫為S>,再S返回?cái)?shù)據(jù)給F)
先在F中使用startActivityForResult方法向S傳遞一個(gè)唯一的請(qǐng)求碼桦踊,
然后在S中使用setResult方法將結(jié)果碼和數(shù)據(jù)返回給F椅野,
最后F在onActivityResult中通過請(qǐng)求碼和結(jié)果碼拿到返回的數(shù)據(jù)。

//F中:
Intent intent = new Intent(F.this,S.class);
startActivityForResult(intent,1);//這里請(qǐng)求碼為1

//S中:
Intent intent = new Intent();
intent.putExtra("dataReturn","I am dataReturn.");
setResult(RESULT_OK,intent);
//第一個(gè)參數(shù)一般只使用RESULT_OK或RESULT_CANCELED這兩個(gè)值

//F中:
@Override
protected void onActivityResult(int requestCode,int resultCode,Intent data){
  //第一個(gè)參數(shù)為請(qǐng)求碼籍胯,是為了區(qū)分是哪個(gè)activity返回的數(shù)據(jù)竟闪,即數(shù)據(jù)來源
  //第二個(gè)參數(shù)是判斷處理結(jié)果是否成功
  //第三個(gè)參數(shù)就是返回的數(shù)據(jù)
  switch(requestCode){
    case 1:
      if(resultCode == RESULT_OK){
        String data = intent.getStringExtra("dataReturn");
      }
    break;
  }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市杖狼,隨后出現(xiàn)的幾起案子炼蛤,更是在濱河造成了極大的恐慌,老刑警劉巖蝶涩,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件理朋,死亡現(xiàn)場(chǎng)離奇詭異絮识,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)嗽上,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門笋除,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人炸裆,你說我怎么就攤上這事垃它。” “怎么了烹看?”我有些...
    開封第一講書人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵国拇,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我惯殊,道長(zhǎng)酱吝,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任土思,我火速辦了婚禮务热,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘己儒。我一直安慰自己崎岂,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開白布闪湾。 她就那樣靜靜地躺著冲甘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪途样。 梳的紋絲不亂的頭發(fā)上江醇,一...
    開封第一講書人閱讀 52,262評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音何暇,去河邊找鬼陶夜。 笑死,一個(gè)胖子當(dāng)著我的面吹牛裆站,可吹牛的內(nèi)容都是我干的条辟。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼遏插,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼捂贿!你這毒婦竟也來了纠修?” 一聲冷哼從身側(cè)響起胳嘲,我...
    開封第一講書人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎扣草,沒想到半個(gè)月后了牛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體颜屠,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年鹰祸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了甫窟。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蛙婴,死狀恐怖粗井,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情街图,我是刑警寧澤浇衬,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站餐济,受9級(jí)特大地震影響耘擂,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜絮姆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一醉冤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧篙悯,春花似錦蚁阳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至移宅,卻和暖如春归粉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背漏峰。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工糠悼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人浅乔。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓倔喂,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親靖苇。 傳聞我的和親對(duì)象是個(gè)殘疾皇子席噩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容