Android中的四大組件:

一:Activity:

Activity 是Android 四大組件之一球昨,用于展示界面烤蜕。Activity 中所有操作都與用戶密切相關,是一個負責與用戶交互的組件韵吨,它上面可以顯示一些控件也可以監(jiān)聽并處理用戶的事件匿垄。一個Activity 通常就是一個單獨的屏幕,Activity 之間通過Intent 進行通信学赛。

一年堆、關閉當前Activity

在Activity 中調用finish()方法即可關閉當前Activity。

二盏浇、啟動一個Activity 時獲取該Activity 銷毀時的返回值

如果想讓我們的MainActivity 打開ContactListActivity变丧,同時能夠獲取到ContactListActivity銷毀時返回的數(shù)據(jù), 那么就不能通過startActivity(Intent) 方法去啟動ContactListActivity了绢掰。必須使用startActivityForResult(Intent intent, int requestCode)方法痒蓬,該方法必須跟onActivityResult(int requestCode,int resultCode, Intent data)方法結合著使用才行,當MainActivity 啟動的ContactListActivity銷毀前滴劲,如果ContactListActivity調用了setResult(int resultCode, Intent data)方法攻晒,那么系統(tǒng)就會調用MainActivity 的onActivityResult()方法,同時將數(shù)據(jù)Intent 的形式傳遞過來班挖。

Activity 的生命周期

學到這里我們有必要對Activity 有一個全新的認識鲁捏。Activity 已經不能再簡單的認為就是一個普通的類,其生命周期就是類的加載萧芙,對象的的創(chuàng)建和對象的卸載那么簡單给梅。Activity 從創(chuàng)建到銷毀,整個生命周期是一個非常復雜的過程双揪,該過程由Android 系統(tǒng)負責維護动羽。

Activity 的3 種狀態(tài)

我們人類有嬰幼兒時期、青少年時期渔期、中老年時期运吓,Activity 一樣也有3 種狀態(tài):Resumed、Paused疯趟、Stopped拘哨,這三種狀態(tài)是Android 官方給出的,我們翻譯過來可以理解為:激活或運行狀態(tài)信峻、暫停狀態(tài)宅静、停止狀態(tài)。這3 種狀態(tài)的特點如下:

Resumed 狀態(tài):Activity 位于前端位置站欺,并且獲取到了用戶的焦點姨夹。也就是當前Activity 完全可見也可用纤垂。

注意:在Android 中目前只允許同時只能有一個Activity 位于前端位置。

Paused 狀態(tài):如果另外一個Activity 位于前端位置并且獲取了焦點磷账,但是該Activity 還依然可見峭沦,那么該Activity 就處于了Paused 狀態(tài)。比如如果另外一個Activity 雖然位于前端逃糟,但是是透明的或者沒有占滿整個屏幕吼鱼,那么就會出現(xiàn)上面的這種情況。位于Paused 狀態(tài)的Activity 依然是“存活”著的绰咽,但是如果系統(tǒng)內存極端的不足菇肃,那么就有可能被系統(tǒng)“殺死”以便釋放內存。

Stopped 狀態(tài):當另外一個Activity 完全將該Activity 遮蓋住的情況下取募,那么該Activity 就處于停止狀態(tài)了琐谤。位于停止狀態(tài)的Activity 依然“活著”,但是它已經對用戶完全不可見了玩敏,因此只要系統(tǒng)需要釋放內存就會將該Activity“殺死”斗忌。

我們編寫的代碼要根據(jù)Activity 的不同狀態(tài)讓其做不同的工作,比如如果我們的Activity 是用于播放視頻的旺聚,那么當其位于Resumed 狀態(tài)時我們可以讓視頻正常的播放织阳,當Activity 位于Paused 狀態(tài)的時候,我們也應該讓我們的視頻暫停播放砰粹,當Activity 位于Stopped 狀態(tài)時我們應該停止播放視頻并釋放資源唧躲。

那么如何讓我們的程序員能夠感知到Activity 的狀態(tài)變化呢?Android 系統(tǒng)為了將Activity 狀態(tài)的變化通知給我們在Activity 中提供了7 個回調方法碱璃。我們只需要在不同的回調方法中完成不同的工作即可弄痹。

Activity 生命周期的7 個回調方法

方法名

特點

OnCreate

當Activity 第一次創(chuàng)建時被調用,在該方法中我們應該執(zhí)行創(chuàng)建視圖厘贼、初始化數(shù)據(jù)等工作界酒。該方法被調用之后緊接著就是調用onStart 方法圣拄。

onStart

當Activity 對用戶可見前被系統(tǒng)調用嘴秸。

onResume

當Activity 可以跟用戶交互前被調用,該方法被調用后Activity 就處于Resumed 狀態(tài)庇谆。

onPause

當另外一個Activity 即將成為Resumed 狀態(tài)前調用岳掐,在該方法中應該保存臨時數(shù)據(jù)、停止動畫饭耳、暫停視頻播放器等串述。必須要注意的就是該方法執(zhí)行必須要快,因為只有當該方法執(zhí)行過之后寞肖,另外一個Activity 才會成為Resumed 狀態(tài)纲酗,不然會造成Activity 直接切換的“卡頓”現(xiàn)象衰腌。

onStop

當Activity 對用戶已經完全不可見的時候就會調用該方法。當另外一個Activity 已經成為Resumed 狀態(tài)或者當前Activity 被銷毀的情況下會導致當前Activity 不可見觅赊。

onDestory

當Activity 被銷毀前調用右蕊。當前Activity 調用finish()方法或者系統(tǒng)為了釋放內存而將其銷毀都會調用該方法。

onRestart

當Activity 處于onStop 狀態(tài)之后吮螺,如果重新啟動則會調用該方法饶囚。比如如果當前Activity位于Resumed 狀態(tài),此時我們按了Home 鍵鸠补,那么Activity 就完全不可見了萝风,onStop 方法就會被執(zhí)行,然后再長按Home 鍵再將該Activity 重新啟動起來就會調用onRestart 方法紫岩。

Activity 生命周期圖

下圖是Android官方給出的Activity 生命周期圖:

橫豎屏切換時Activity 的生命周期

Android 手機在橫豎屏切換時规惰,默認情況下會把Activity 先銷毀再創(chuàng)建,模擬器橫豎屏切換的快捷鍵是Ctrl+F11被因。

在類似手機游戲卿拴、手機影音這一類的應用中,這個體驗是非常差的梨与。不讓Activity 在橫豎屏切換時銷毀堕花,只需要在清單文件聲明Activity 時配置節(jié)點的幾個屬性即可,其方式如下:

一. 4.0 以下版本:

android:configChanges="orientation|keyboardHidden"

二. 4.0 以上版本:

android:configChanges="orientation|screenSize"

三. 4.0 以上版本:

android:configChanges="orientation|keyboardHidden|screenSize"

將該參數(shù)配置到Activity 中后再切換屏幕方向粥鞋,那么Activity 就不會再銷毀和重新創(chuàng)建了缘挽。但是配置了該參數(shù)僅僅是不讓Activity 銷毀和重建,Activity 界面依然會跟著屏幕方向重新調整呻粹,那么如何固定Activity 的方向呢壕曼?

固定Activity 的方向

想固定Activity 的方向其實比較簡單,有兩種方法:

1等浊、通過配置文件

在AndroidManifest.xml 中的activity 節(jié)點中添加如下屬性腮郊。

android:screenOrientation="portrait"

該屬性通常有兩個常量值,portrait:垂直方向筹燕,landscape:水平方向轧飞。

2、通過代碼

在Activity 的onCreate 方法中執(zhí)行如下方法撒踪。

//垂直方向

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

//水平方向

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

Activity 的啟動模式

Activity 的任務棧

Task Stack(任務棧)是一個具有棧結構的容器过咬,可以放置多個Activity 實例。啟動一個應用制妄,系統(tǒng)就會為之創(chuàng)建一個task掸绞,來放置根Activity;默認情況下耕捞,一個Activity 啟動另一個Activity 時衔掸,兩個Activity是放置在同一個task 中的烫幕,后者被壓入前者所在的task 棧,當用戶按下back 鍵敞映,后者從task 中被彈出纬霞,

前者又顯示在屏幕前,特別是啟動其他應用中的Activity 時驱显,兩個Activity 對用戶來說就好像是屬于同一個應用诗芜;系統(tǒng)task 和應用task 之間是互相獨立的,當我們運行一個應用時埃疫,按下Home 鍵回到主屏伏恐,啟動另一個應用,這個過程中栓霜,之前的task 被轉移到后臺翠桦,新的task 被轉移到前臺,其根Activity 也會顯示到

幕前胳蛮,過了一會之后销凑,再次按下Home 鍵回到主屏,再選擇之前的應用仅炊,之前的task 會被轉移到前臺斗幼,系統(tǒng)仍然保留著task 內的所有Activity 實例,而那個新的task 會被轉移到后臺抚垄,如果這時用戶再做后退等動作蜕窿,就是針對該task 內部進行操作了。

任務棧的設計是為了提高用戶體驗呆馁,但是也有其不足的地方桐经。任務棧的缺點如下:

1、每開啟一次頁面都會在任務棧中添加一個Activity浙滤,而只有任務棧中的Activity 全部清除出棧時阴挣,任務棧被銷毀,程序才會退出纺腊,這樣的設計在某種程度上可能造成了用戶體驗差畔咧,需要點擊多次返回才可以把程序退出了。

2摹菠、每開啟一次頁面都會在任務棧中添加一個Activity 還會造成數(shù)據(jù)冗余, 重復數(shù)據(jù)太多, 會導致內存溢出的問題(OOM)盒卸。

Andriod給出的官方圖:

為了解決任務棧產生的問題骗爆,Android 為Activity 設計了啟動模式次氨,那么下面的內容將介紹Android 中Activity 的啟動模式,這也是最重要的內容之一摘投。

Activity 的啟動模式

啟動模式(launchMode)在多個Activity 跳轉的過程中扮演著重要的角色煮寡,它可以決定是否生成新的Activity 實例虹蓄,是否重用已存在的Activity 實例,是否和其他Activity 實例共用一個task幸撕。

Activity 一共有以下四種launchMode:standard薇组、singleTop、singleTask坐儿、singleInstance律胀。我們可以在AndroidManifest.xml 配置的android:launchMode 屬性為以上四種之一即可。

standard: 標準啟動模式

特點:默認啟動模式, 每次激活Activity時(startActivity)貌矿,都創(chuàng)建Activity實例炭菌,并放入任務棧.

singleTop:單一頂部模式

特點:如果activity已經被開啟,而且是在棧頂逛漫,就不會在創(chuàng)建當前這個activity的實例黑低,而是復用這個已經開啟的activity,但是如果不是在棧頂酌毡,就會初始化一個新的實例克握,在整個棧里允許有多個實例

singleTask:單一任務棧

特點:當前棧里只允許有一個當前activity的實例,如果要開啟的activity在棧里存在枷踏,并且在底部菩暗,就會移除這個activity上面所有的activity

應用場景:如果這個activity非常消耗cpu和內存,建議把這個activity的啟動模式設置為singleTask旭蠕,瀏覽器的browserActivity 設置的就是

singleinstance:單一實例

特點:整個手機操作系統(tǒng)只有一個實例勋眯,并且是單獨運行在自己的任務棧里

應用場景:通話界面的activity

Note:

Activity的啟動模式是面試幾乎都會問到的一個知識點,也是很重要的一個知識點下梢,在項目開發(fā)中經常會用到啟動模式來幫助我們解決一些比較難解決的bug客蹋,也可以幫助我們去優(yōu)化一個項目的任務棧,防止界面太多導致卡頓和OOM孽江。

二:Broadcast:

在Android 中讶坯,Broadcast 是一種廣泛運用的在應用程序之間傳輸信息的機制。而BroadcastReceiver 是對發(fā)送出來的Broadcast 進行過濾接受并響應的一類組件岗屏,是Android 四大組件之一辆琅。

廣播接收者(BroadcastReceiver)用于接收廣播的,廣播的發(fā)送是通過調用sendBroadcast(Intent)/sendOrderedBroadcast(Intent)來實現(xiàn)的这刷。通常一個廣播可以被多個廣播接收者所接收婉烟。

廣播被分為兩種不同的類型:“普通廣播(Normal Broadcasts)”也叫無序廣播和“有序廣播(OrderedBroadcasts)”。

注意:如果我們的應用退出了暇屋,那么就無法監(jiān)聽到該廣播似袁,可能有人說是因為退出的時候調用了MainActivity 的onDestory()方法,而onDestory()方法中調用了unregisterReceiver(BroadCastReceiver)方法,確實如此的昙衅。那么如果我們將onDestory()方法中的unregisterReceiver()方法給去掉會是什么樣的情況呢扬霜?那我們就一起試一下吧!

將MainActivity.java 中的unregisterReceiver()去掉之后重新運行上面的項目而涉,然后點擊back 鍵著瓶,發(fā)現(xiàn)logcat 輸入了如下錯誤信息:

上面的信息說我們的MainActivity 導致了IntentReceiver 的泄露。ScreenReceiver 在MainActivity 中被注冊了但是當MainActivity 銷毀的時候沒有被反注冊啼县。

可見要想讓我們的代碼更加完善材原,必須在onDestory 中或者其他地方(必須保證Activity 銷毀前)將接收者給反注冊掉。

三:Serivce:

Serivce的基本概念

Android 官方文檔對Service 的解釋如下:

翻譯:

Service 是應用組件之一季眷,用來執(zhí)行需要長時間運行的操作华糖,Service 運行在后臺并且跟用戶沒有交互界面。第三方應用的組件(指四大組件的任意一種)可以啟動一個Service瘟裸,一旦啟動起來客叉,該Service 就一直在后臺運行,就算用戶已經將該應用置為后臺進程话告。另外兼搏,組件也可以通過綁定的形式跟一個Service

進行交互,甚至完成進程間通信沙郭。比如:Service 可以在后臺處理網絡傳輸佛呻、播放音樂、進行I/O 流的讀寫或者跟內容提供者進行交互病线。

Service 的特點如下:

Service 在Android 中是一種長生命周期的組件吓著,它不實現(xiàn)任何用戶界面,是一個沒有界面的Activity

Service 長期在后臺運行送挑,執(zhí)行不關乎界面的一些操作比如:網易新聞服務绑莺,每隔1 分鐘去服務查看是否有最新新聞

Service 和Thread 有點相似,但是使用Thread 不安全惕耕,不嚴謹

Service 和其他組件一樣纺裁,都是運行在主線程中,因此不能用它來做耗時的操作

Service 的生命周期回調函數(shù)

和Activity 一樣司澎,service 也有一系列的生命周期回調函數(shù)欺缘,你可以實現(xiàn)它們來監(jiān)測service 狀態(tài)的變化恐似,并且在適當?shù)臅r候執(zhí)行適當?shù)墓ぷ鳌?/p>

下面的service 展示了每一個生命周期的方法蝇棉,也是官網給出的demo:

注意:不同于Activity 的生命周期回調方法,Service 不須調用父類的生命周期回調方法仇参。

Service的生命周期圖

官方給出的Service 生命周期圖如下所示蛤铜。該圖左側展示的是用startService()方法啟動的Service的生命周期嫩絮,右側展示的是用bindService()方法啟動的Service 的生命周期丛肢。

這個圖說明了Service 典型的回調方法,盡管這個圖中將開啟的Service 和綁定的Service 分開絮记,但是我們需要記住,任何Service 都潛在地允許被綁定虐先。所以怨愤,一個被開啟的Service 仍然可能被綁定。實現(xiàn)這些方法蛹批,可以看到兩層嵌套的Service 的生命周期撰洗。

整體生命周期(The entire lifetime)

Service 整體的生命時間是從onCreate()被調用開始,到onDestroy()方法返回為止腐芍。和Activity 一樣差导,Service 在onCreate()中進行它的初始化工作,在onDestroy()中釋放殘留的資源猪勇。比如设褐,一個音樂播放service 可以在onCreate()中創(chuàng)建播放音樂的線程,在onDestory()中停止這個線程泣刹。

onCreate() 和onDestroy()會被所有的Service 調用助析,不論Service 是通過startService()還是bindService()建立的。

積極活動的生命周期(The active lifetime)

Service 積極活動的生命周期(active lifetime)是從onStartCommand() 或onBind()被調用開始椅您,它們各自處理由startService()或bindService()方法傳過來的Intent 對象外冀。如果service 是被開啟的,那么它的活動生命周期和整個生命周期一同結束掀泳。如果service 是被綁定的雪隧,它們它的活動生命周期是在onUnbind()方法返回后結束。

注意:

盡管一個被開啟的service 是通過調用stopSelf() 或stopService()來停止的员舵,沒有一個對應的回調函數(shù)與之對應脑沿,即沒有onStop()回調方法。所以马僻,當調用了停止的方法捅伤,除非這個service 和客戶組件綁定,否則系統(tǒng)將會直接銷毀它巫玻,onDestory()方法會被調用丛忆,并且是這個時候唯一會被調用的回調方法。

四:ContentProvider:

內容提供者ContentProvider仍秤,是Android 的四大組件之一熄诡。內容提供者是應用程序之間共享數(shù)據(jù)的接口。

Android 系統(tǒng)將這種機制應用到方方面面诗力,比如:聯(lián)系人(通訊錄應用程序)Provider 專為不同應用程序提供聯(lián)系人數(shù)據(jù)凰浮;短信(短信應用程序)Provider 專為不同應用程序提供系統(tǒng)短信信息我抠。當應用繼承ContentProvider 類,并重寫該類用于提供數(shù)據(jù)和存儲數(shù)據(jù)的方法袜茧,就可以向其他應用共享其數(shù)據(jù)菜拓。雖然使用其他方法也可以對外共享數(shù)據(jù),但數(shù)據(jù)訪問方式會因數(shù)據(jù)存儲的方式而不同笛厦,如:采用文件方式對外共享數(shù)據(jù)纳鼎,需要進行文件操作讀寫數(shù)據(jù);采用SharedPreferences 共享數(shù)據(jù)裳凸,需要使用SharedPreferences API 讀寫數(shù)據(jù)贱鄙。而使用ContentProvider 共享數(shù)據(jù)的好處是統(tǒng)一了數(shù)據(jù)訪問方式。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末姨谷,一起剝皮案震驚了整個濱河市逗宁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌梦湘,老刑警劉巖瞎颗,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異捌议,居然都是意外死亡言缤,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進店門禁灼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來管挟,“玉大人,你說我怎么就攤上這事弄捕∑ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵守谓,是天一觀的道長穿铆。 經常有香客問我,道長斋荞,這世上最難降的妖魔是什么荞雏? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮平酿,結果婚禮上凤优,老公的妹妹穿的比我還像新娘。我一直安慰自己蜈彼,他們只是感情好筑辨,可當我...
    茶點故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著幸逆,像睡著了一般棍辕。 火紅的嫁衣襯著肌膚如雪暮现。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天楚昭,我揣著相機與錄音栖袋,去河邊找鬼。 笑死抚太,一個胖子當著我的面吹牛塘幅,可吹牛的內容都是我干的。 我是一名探鬼主播凭舶,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼晌块,長吁一口氣:“原來是場噩夢啊……” “哼爱沟!你這毒婦竟也來了帅霜?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤呼伸,失蹤者是張志新(化名)和其女友劉穎身冀,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體括享,經...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡搂根,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了铃辖。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片剩愧。...
    茶點故事閱讀 38,673評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖娇斩,靈堂內的尸體忽然破棺而出仁卷,到底是詐尸還是另有隱情,我是刑警寧澤犬第,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布锦积,位于F島的核電站,受9級特大地震影響歉嗓,放射性物質發(fā)生泄漏丰介。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一鉴分、第九天 我趴在偏房一處隱蔽的房頂上張望哮幢。 院中可真熱鬧,春花似錦志珍、人聲如沸家浇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽钢悲。三九已至点额,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間莺琳,已是汗流浹背还棱。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留惭等,地道東北人珍手。 一個月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像辞做,于是被迫代替她去往敵國和親琳要。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,562評論 2 349

推薦閱讀更多精彩內容