一族淮,Activity面試詳解
1,activity的四種狀態(tài)
- running 活動(dòng)狀態(tài)凭涂。用戶點(diǎn)擊屏幕祝辣,屏幕做出響應(yīng)。置于棧頂
- paused 失去焦點(diǎn)狀態(tài)导盅。用戶點(diǎn)擊屏幕较幌,無(wú)響應(yīng)揍瑟。(可能被新的非全屏的activity或一個(gè)透明的activity覆蓋)白翻,成員變量,狀態(tài)信息存在。內(nèi)存緊張滤馍,activity回收
- stopped 該activity被另一個(gè)activity完全覆蓋的時(shí)候岛琼。成員變量,狀態(tài)信息存在巢株。內(nèi)存緊張槐瑞,activity回收
- killed activity被回收
2,activity的生命周期
activity啟動(dòng)->onCreate()->onStart()->onResume()
點(diǎn)擊home鍵回到主界面(activity不可見)->onPause()->onStop()
當(dāng)我們?cè)俅位氐皆璦ctivity時(shí)->onRestart()->onStart()->onResume()
退出當(dāng)前activity時(shí)->onPause()->onStop()->onDestroy()
onCreate :Activity第一次被實(shí)例化的時(shí)候系統(tǒng)會(huì)調(diào)用阁苞,整個(gè)生命周期只調(diào)用1次該方法困檩。
通常用于初始化設(shè)置: 1、為Activity設(shè)置所要使用的布局文件那槽。2悼沿、為安卓控件綁定監(jiān)聽器等靜態(tài)的設(shè)置操作。onStart(
可見不可交互
):當(dāng)Activity可見未獲得用戶焦點(diǎn)不能交互時(shí)系統(tǒng)會(huì)調(diào)用骚灸。onResume(
可見可交互
) :當(dāng)Activity和用戶發(fā)生交互的時(shí)候糟趾,觸發(fā)該方法。onPause (
有一點(diǎn)可見不能交互
):當(dāng)一個(gè)正在前臺(tái)運(yùn)行的Activity因?yàn)槠渌腁ctivity需要前臺(tái)運(yùn)行而轉(zhuǎn)入后臺(tái)運(yùn)行的時(shí)候甚牲,觸發(fā)該方法义郑。onStop(
不可見不能交互
):當(dāng)Activity被其他的Activity完全覆蓋不可見時(shí),觸發(fā)該方法丈钙,如果內(nèi)存緊張非驮,系統(tǒng)會(huì)直接結(jié)束這個(gè)Activity,而不會(huì)觸發(fā) onStop 方法雏赦。onRestart (
由不可見到可見
):當(dāng)處于停止?fàn)顟B(tài)的Activity需要再次展現(xiàn)給用戶的時(shí)候院尔,觸發(fā)該方法。onDestroy :當(dāng)Activity(用戶調(diào)用finish()或系統(tǒng)由于內(nèi)存不足)被系統(tǒng)銷毀時(shí)調(diào)用,(整個(gè)生命周期只調(diào)用1次)用來(lái)釋放onCreate ()方法中創(chuàng)建的資源,如結(jié)束線程喉誊,清空數(shù)據(jù)邀摆,注銷廣播等。和 onStop 方法一樣伍茄,如果內(nèi)存緊張栋盹,系統(tǒng)會(huì)直接結(jié)束這個(gè)Activity而不會(huì)觸發(fā)該方法。
具體區(qū)別 https://blog.csdn.net/superjunjin/article/details/44674917
3敷矫,android進(jìn)程優(yōu)先級(jí)
參考自:https://blog.csdn.net/qinxiandiqi/article/details/51744782
android對(duì)于所有進(jìn)程的處理態(tài)度都是盡可能不殺死
例获。然而,資源總共就那么多曹仗,要是對(duì)所有進(jìn)程都保持寬容的話榨汤,資源總會(huì)有消耗殆盡的時(shí)候。因此怎茫,在內(nèi)存不足的情況收壕,android系統(tǒng)需要根據(jù)一定的策略妓灌,選擇性的殺死部分進(jìn)程。這個(gè)策略就是對(duì)所有的進(jìn)程標(biāo)記優(yōu)先級(jí)蜜宪,優(yōu)先級(jí)低的先殺死
虫埂。
android將進(jìn)程的優(yōu)先級(jí)分為5個(gè)層次,按照優(yōu)先級(jí)由高到低排列如下:
(1)前臺(tái)進(jìn)程(Foreground process)圃验。
它表明用戶正在與該進(jìn)程進(jìn)行交互操作
掉伏,android系統(tǒng)依據(jù)下面的條件來(lái)將一個(gè)進(jìn)程標(biāo)記為前臺(tái)進(jìn)程:
- 該進(jìn)程持有一個(gè)用戶正在與其交互的Activity(也就是這個(gè)activity的生命周期方法走到了onResume()方法)。
- 該進(jìn)程持有一個(gè)Service澳窑,并且這個(gè)Service與一個(gè)用戶正在交互中的Activity進(jìn)行綁定斧散。
- 該進(jìn)程持有一個(gè)前臺(tái)運(yùn)行模式的Service(也就是這個(gè)Service調(diào)用了startForegroud()方法)。
- 該進(jìn)程持有一個(gè)正在執(zhí)行生命周期方法(onCreate()摊聋、onStart()颅湘、onDestroy()等)的Service。
- 該進(jìn)程持有一個(gè)正在執(zhí)行onReceive()方法的BroadcastReceiver栗精。
一般情況下闯参,不會(huì)有太多的前臺(tái)進(jìn)程
。殺死前臺(tái)進(jìn)程是操作系統(tǒng)最后無(wú)可奈何的做法悲立。當(dāng)內(nèi)存嚴(yán)重不足的時(shí)候鹿寨,前臺(tái)進(jìn)程一樣會(huì)被殺死。
(2)可見進(jìn)程(Visible process)薪夕。
它表明雖然該進(jìn)程沒有持有任何前臺(tái)組件
脚草,但是它還是能夠影響到用戶看得到的界面。android系統(tǒng)依據(jù)下面的條件將一個(gè)進(jìn)程標(biāo)記為可見進(jìn)程:
- 該進(jìn)程持有一個(gè)非前臺(tái)Activity原献,但這個(gè)Activity依然能被用戶看到(也就是這個(gè)Activity調(diào)用了onPause()方法)馏慨。例如,當(dāng)一個(gè)activity啟動(dòng)了一個(gè)對(duì)話框姑隅,這個(gè)activity就被對(duì)話框擋在后面写隶。
- 該進(jìn)程持有一個(gè)與可見(或者前臺(tái))Activity綁定的Service。
(3)服務(wù)進(jìn)程(Service process)讲仰。
除了符合前臺(tái)進(jìn)程和可見進(jìn)程條件的Service大猛,其它的Service都會(huì)被歸類為服務(wù)進(jìn)程陨享。
(4)后臺(tái)進(jìn)程(Background process)抖格。
持有不可見Activity(調(diào)用了onStop()方法)的進(jìn)程即為后臺(tái)進(jìn)程
生逸。通常情況下都會(huì)有很多后臺(tái)進(jìn)程,當(dāng)內(nèi)存不足的時(shí)候趁矾,在所有的后臺(tái)進(jìn)程里面耙册,會(huì)按照LRU(最近使用)規(guī)則,優(yōu)先回收最長(zhǎng)時(shí)間沒有使用過的進(jìn)程
毫捣。
(5)空進(jìn)程(Empty process)详拙。不持有任何活動(dòng)組件的進(jìn)程
帝际。保持這種進(jìn)程只有一個(gè)目的,就是為了緩存溪厘,以便下一次啟動(dòng)該進(jìn)程中的組件時(shí)能夠更快響應(yīng)
胡本。當(dāng)資源緊張的時(shí)候牌柄,系統(tǒng)會(huì)平衡進(jìn)程緩存和底層的內(nèi)核緩存情況進(jìn)行回收畸悬。
如果一個(gè)進(jìn)程同時(shí)滿足上述5種優(yōu)先級(jí)中的多個(gè)等級(jí)條件,android系統(tǒng)會(huì)優(yōu)先選取其中最高的等級(jí)作為該進(jìn)程的優(yōu)先級(jí)
珊佣。例如蹋宦,一個(gè)進(jìn)程持有一個(gè)Service(服務(wù)進(jìn)程等級(jí))和一個(gè)前臺(tái)Activity(前臺(tái)進(jìn)程等級(jí)),那么操作系統(tǒng)會(huì)將這個(gè)進(jìn)程標(biāo)記為前臺(tái)進(jìn)程咒锻。
另外需要注意的是冷冗,如果一個(gè)進(jìn)程為另外一個(gè)進(jìn)程提供服務(wù),那么這個(gè)進(jìn)程的優(yōu)先級(jí)不會(huì)低于享受服務(wù)的進(jìn)程
惑艇。例如蒿辙,假設(shè)進(jìn)程A中的content provider為進(jìn)程B提供服務(wù),或者進(jìn)程A中有一個(gè)Service與進(jìn)程B中的組件進(jìn)程綁定滨巴,那么進(jìn)程A的優(yōu)先級(jí)至少要與進(jìn)程B一致思灌,或者高于進(jìn)程B。
4恭取,activity啟動(dòng)模式
參考自:https://blog.csdn.net/mynameishuangshuai/article/details/51491074
實(shí)際應(yīng)用時(shí)泰偿,取類的TaskId查看所屬棧id
,類的hashCode查看類實(shí)例id
(1)standard-標(biāo)準(zhǔn)模式
這個(gè)模式是默認(rèn)
的啟動(dòng)模式蜈垮,即標(biāo)準(zhǔn)模式耗跛。每次啟動(dòng)一個(gè)Activity都會(huì)重寫創(chuàng)建一個(gè)新的實(shí)例
,不管這個(gè)實(shí)例存不存在攒发,這種模式下调塌,誰(shuí)啟動(dòng)了該模式的Activity,該Activity就屬于啟動(dòng)它的Activity的任務(wù)棧中
惠猿。這個(gè)Activity它的onCreate()烟阐,onStart(),onResume()方法都會(huì)被調(diào)用紊扬。
(2)singleTop-棧頂復(fù)用模式
這個(gè)模式下蜒茄,如果新的activity已經(jīng)位于棧頂,那么這個(gè)Activity不會(huì)被重寫創(chuàng)建餐屎,同時(shí)它的onNewIntent方法會(huì)被調(diào)用
(onCreate()檀葛,onStart()方法不會(huì)被調(diào)用),通過此方法的參數(shù)我們可以去除當(dāng)前請(qǐng)求的信息腹缩。如果棧頂不存在該Activity的實(shí)例屿聋,則情況與standard模式相同空扎。
taskAffinity
standard和singleTop啟動(dòng)模式都是在原任務(wù)棧中新建Activity實(shí)例,不會(huì)啟動(dòng)新的Task润讥,即使你指定了taskAffinity屬性
转锈。
那么什么是taskAffinity屬性呢,可以簡(jiǎn)單的理解為任務(wù)相關(guān)性楚殿。
- 這個(gè)參數(shù)標(biāo)識(shí)了一個(gè)Activity所需任務(wù)棧的名字撮慨,默認(rèn)情況下,所有Activity所需的任務(wù)棧的名字為應(yīng)用的包名
- 我們可以單獨(dú)指定每一個(gè)Activity的taskAffinity屬性覆蓋默認(rèn)值
- 一個(gè)任務(wù)的affinity決定于這個(gè)任務(wù)的根activity(root activity)的taskAffinity(
沒明白
) - 在概念上脆粥,具有相同的affinity的activity(即設(shè)置了相同taskAffinity屬性的activity)屬于同一個(gè)任務(wù)
- 為一個(gè)activity的taskAffinity設(shè)置一個(gè)空字符串砌溺,表明這個(gè)activity不屬于任何task
(3)singleTask-棧內(nèi)復(fù)用模式
這個(gè)模式十分復(fù)雜,有各式各樣的組合变隔。在這個(gè)模式下规伐,如果棧中存在這個(gè)Activity的實(shí)例就會(huì)復(fù)用這個(gè)Activity
,不管它是否位于棧頂匣缘,復(fù)用時(shí)猖闪,會(huì)將它上面的Activity全部出棧
,并且會(huì)回調(diào)該實(shí)例的onNewIntent方法肌厨。其實(shí)這個(gè)過程還存在一個(gè)任務(wù)棧的匹配培慌,因?yàn)檫@個(gè)模式啟動(dòng)時(shí),會(huì)在自己需要的任務(wù)棧中尋找實(shí)例夏哭,這個(gè)任務(wù)棧就是通過taskAffinity屬性指定
检柬。如果這個(gè)任務(wù)棧不存在,則會(huì)創(chuàng)建這個(gè)任務(wù)棧竖配。
singleTask啟動(dòng)模式啟動(dòng)Activity時(shí)何址,首先會(huì)根據(jù)taskAffinity去尋找當(dāng)前是否存在一個(gè)對(duì)應(yīng)名字的任務(wù)棧
- 如果不存在,則會(huì)創(chuàng)建一個(gè)新的Task进胯,并創(chuàng)建新的Activity實(shí)例入棧到新創(chuàng)建的Task中去
- 如果存在用爪,則得到該任務(wù)棧,查找該任務(wù)棧中是否存在該Activity實(shí)例
- 如果存在實(shí)例胁镐,則將它上面的Activity實(shí)例都出棧偎血,然后回調(diào)啟動(dòng)的Activity實(shí)例的onNewIntent方法
- 如果不存在該實(shí)例,則新建Activity盯漂,并入棧
此外颇玷,我們可以將兩個(gè)不同App中的Activity設(shè)置為相同的taskAffinity,這樣雖然在不同的應(yīng)用中就缆,但是Activity會(huì)被分配到同一個(gè)Task中去帖渠。
(4)singleInstance-全局唯一模式
該模式具備singleTask模式的所有特性外,與它的區(qū)別就是竭宰,這種模式下的Activity會(huì)單獨(dú)占用一個(gè)Task棧空郊,具有全局唯一性
份招,即整個(gè)系統(tǒng)中就這么一個(gè)實(shí)例,如果在啟動(dòng)這樣的Activiyt時(shí)狞甚,已經(jīng)存在了一個(gè)實(shí)例锁摔,那么會(huì)把它所在的任務(wù)調(diào)度到前臺(tái),重用這個(gè)實(shí)例哼审。
總結(jié):
standard谐腰,創(chuàng)建一個(gè)新的Activity。
singleTop棺蛛,棧頂不是該類型的Activity怔蚌,創(chuàng)建一個(gè)新的Activity巩步。否則旁赊,onNewIntent。
singleTask椅野,回退棧中沒有該類型的Activity终畅,創(chuàng)建Activity,否則竟闪,onNewIntent+ClearTop离福。
singleInstance,回退棧中炼蛤,只有這一個(gè)Activity妖爷,沒有其他Activity。
應(yīng)用場(chǎng)景:
參考自:https://blog.csdn.net/qq_35114086/article/details/52614714
參考自:https://blog.csdn.net/CodeEmperor/article/details/50481726
singleTop
1理朋,適合接收通知啟動(dòng)的內(nèi)容顯示頁(yè)面絮识。
比如新聞客戶端收到了100個(gè)推送,你每次點(diǎn)一下推送他都會(huì)走一遍某個(gè)activiy(顯示新聞只用一個(gè)activity嗽上,只是內(nèi)容不同而已)的oncreate次舌,onstart,代價(jià)就是創(chuàng)建了那么多的activity(不要以為只有推送兽愤,比如qq消息提醒)
a彼念,耗內(nèi)存
b, 走了100次的跳轉(zhuǎn)動(dòng)畫 ,也是醉了
2浅萧,某些業(yè)務(wù)需求是自己的activity跳轉(zhuǎn)到自己的逐沙。
比如 歌曲搜索 你又不會(huì)用actionbar,toolbar洼畅,那就在activity上面弄個(gè)假的唄吩案,搜索完了自己跳轉(zhuǎn)自己現(xiàn)實(shí)搜索結(jié)果,那就直接用該模式土思,變化都在onNewIntent()里面對(duì)控件進(jìn)行賦值之類的务热。而且也沒有跳轉(zhuǎn)動(dòng)畫忆嗜,人們以為這個(gè)activity沒有動(dòng)了,多high崎岂。
singleTask
適合作為程序入口點(diǎn)捆毫。
例如瀏覽器的主界面。不管從多少個(gè)應(yīng)用啟動(dòng)瀏覽器冲甘,只會(huì)啟動(dòng)主界面一次绩卤,其余情況都會(huì)走onNewIntent,并且會(huì)清空主界面上面的其他頁(yè)面江醇。
singleInstance
適合需要與程序分離開的頁(yè)面濒憋。
例如鬧鈴提醒,將鬧鈴提醒與鬧鈴設(shè)置分離陶夜。打電話 接通的時(shí)候凛驮。地圖顯示的時(shí)候。
他們都有一個(gè)特點(diǎn) 就是你做完這件事了都會(huì)返回到上一界面 而沒有下一界面条辟。
singleInstance不要用于中間頁(yè)面黔夭,如果用于中間頁(yè)面,跳轉(zhuǎn)會(huì)有問題羽嫡,比如:A -> B (singleInstance) -> C本姥,完全退出后,再次啟動(dòng)杭棵,首先打開的是B婚惫。(ac在一個(gè)棧,退出c后魂爪,退出a,退出ac的棧先舷,再退出b,最后b置于棧頂
)
http://stackoverflow.com/questions/2626218/examples-for-android-launch-modes
5,scheme
參考自:android-Scheme與網(wǎng)頁(yè)跳轉(zhuǎn)原生的三種方式
(1)什么是 URL Scheme甫窟?
android中的scheme是一種頁(yè)面內(nèi)跳轉(zhuǎn)協(xié)議密浑,是一種非常好的實(shí)現(xiàn)機(jī)制,通過定義自己的scheme協(xié)議粗井,可以非常方便跳轉(zhuǎn)app中的各個(gè)頁(yè)面尔破;通過scheme協(xié)議,服務(wù)器可以定制化告訴App跳轉(zhuǎn)那個(gè)頁(yè)面浇衬,可以通過通知欄消息定制化跳轉(zhuǎn)頁(yè)面懒构,可以通過H5頁(yè)面跳轉(zhuǎn)頁(yè)面等
。
(2)URL Scheme應(yīng)用場(chǎng)景:
客戶端應(yīng)用可以向操作系統(tǒng)注冊(cè)一個(gè) URL scheme(在activity中添加scheme的信息
)耘擂,該 scheme 用于從瀏覽器或其他應(yīng)用中啟動(dòng)本應(yīng)用胆剧。通過指定的 URL 字段,可以讓應(yīng)用在被調(diào)起后直接打開某些特定頁(yè)面,比如商品詳情頁(yè)秩霍、活動(dòng)詳情頁(yè)等等篙悯。也可以執(zhí)行某些指定動(dòng)作,如完成支付等铃绒。也可以在應(yīng)用內(nèi)通過 html 頁(yè)來(lái)直接調(diào)用顯示 app 內(nèi)的某個(gè)頁(yè)面鸽照。綜上URL Scheme使用場(chǎng)景大致分以下幾種:
服務(wù)器下發(fā)跳轉(zhuǎn)路徑,客戶端根據(jù)服務(wù)器下發(fā)跳轉(zhuǎn)路徑跳轉(zhuǎn)相應(yīng)的頁(yè)面
H5頁(yè)面點(diǎn)擊錨點(diǎn)颠悬,根據(jù)錨點(diǎn)具體跳轉(zhuǎn)路徑APP端跳轉(zhuǎn)具體的頁(yè)面
APP端收到服務(wù)器端下發(fā)的PUSH通知欄消息矮燎,根據(jù)消息的點(diǎn)擊跳轉(zhuǎn)路徑跳轉(zhuǎn)相關(guān)頁(yè)面
APP根據(jù)URL跳轉(zhuǎn)到另外一個(gè)APP指定頁(yè)面
例:大型公司通過其熱門app的一個(gè)鏈接跳轉(zhuǎn)到其公司的其他app(微信-->騰訊新聞)
深入學(xué)習(xí):Android產(chǎn)品研發(fā)(十一)-->應(yīng)用內(nèi)跳轉(zhuǎn)Scheme協(xié)議
二,F(xiàn)ragment面試詳解
1赔癌,F(xiàn)ragment為什么會(huì)被稱為第五大組件
Fragment有自己的生命周期诞外,但是不能獨(dú)立使用,要加載到activity中使用灾票。
優(yōu)點(diǎn)
(1)fragment相比activity更節(jié)省內(nèi)存峡谊。
(2)能動(dòng)態(tài)靈活的加載到Activity中去配合viewpager使用,UI切換更方便舒適铝条。
2靖苇,F(xiàn)ragment加載到Activity的兩種方式
(1)靜態(tài)加載席噩,fragment作為標(biāo)簽加載到activity的布局文件中
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
(2)動(dòng)態(tài)加載
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
DemoFragment fragment = new DemoFragment();
fragmentTransaction.add(R.id.content, fragment);//容器資源作為標(biāo)志位班缰,把fragment添加到對(duì)應(yīng)的位置
fragmentTransaction.addToBackStack("DemoFragment");
fragmentTransaction.commit();
3,F(xiàn)ragmentPagerAdapter與FragmentStatePagerAdapter(源碼分析)
FragmentPagerAdapter適用于頁(yè)面較少的情況
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
if (DEBUG) Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object
+ " v=" + ((Fragment)object).getView());
mCurTransaction.detach((Fragment)object);
}
FragmentStatePagerAdapter適用于頁(yè)面較多的情況悼枢,每次切換回收內(nèi)存
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
Fragment fragment = (Fragment) object;
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
if (DEBUG) Log.v(TAG, "Removing item #" + position + ": f=" + object
+ " v=" + ((Fragment)object).getView());
while (mSavedState.size() <= position) {
mSavedState.add(null);
}
mSavedState.set(position, fragment.isAdded()
? mFragmentManager.saveFragmentInstanceState(fragment) : null);
mFragments.set(position, null);
mCurTransaction.remove(fragment);
}
4埠忘,F(xiàn)ragment生命周期
[圖片上傳失敗...(image-5dfb7b-1524976453038)]
參考自:https://blog.csdn.net/i_wait_for_you/article/details/70240075
https://www.cnblogs.com/LangZXG/p/6501839.html
https://blog.csdn.net/superjunjin/article/details/44783279
由于Fragment依賴Activity的存在而存在,故在創(chuàng)建時(shí)Activity生命周期中的方法均先于Fragment生命周期中的方法執(zhí)行馒索;相反莹妒,在銷毀時(shí),是先執(zhí)行Fragment生命周期中的方法再執(zhí)行Activity生命周期中的方法绰上。
5旨怠,F(xiàn)ragment通信
在Fragment中調(diào)用Activity中的方法 getActivity
在Fragment中調(diào)用Fragment中的方法 接口回調(diào)
在Fragment中調(diào)用Fragment中的方法 findFragmentById
在Fragment間利用廣播
參考自 https://blog.csdn.net/u012702547/article/details/49786417
6,F(xiàn)ragment部分方法
參考自 https://blog.csdn.net/harvic880925/article/details/44927375(詳細(xì)清晰 寫的太棒了)
add:添加Fragment蜈块,置于棧頂
replace:替換Fragment鉴腻,清空對(duì)應(yīng)容器Fragment,置于棧頂
remove:移除Fragment百揭,顯示下層Fragment
addToBackStack:添加事務(wù)
到回退棧爽哎,置于棧頂
popBackStack:將最上層的事務(wù)
彈出回退棧(根據(jù)具體參數(shù),可以回退到對(duì)應(yīng)的事務(wù))
Fragment回滾以事務(wù)
(FragmentTransaction)為單位器一,一個(gè)事務(wù)可能包含一個(gè)或多個(gè)Fragment
Fragment拓展閱讀
Fragment全解析系列(一):那些年踩過的坑
Square:從今天開始拋棄Fragment吧课锌!
三,service面試詳解
service是一個(gè)一種可以在后臺(tái)執(zhí)行長(zhǎng)時(shí)間運(yùn)行操作而沒有用戶界面的應(yīng)用組件祈秕,可由其他組件啟動(dòng)渺贤,一旦啟動(dòng)可在后臺(tái)長(zhǎng)時(shí)間運(yùn)行雏胃,即使啟動(dòng)它的組件已經(jīng)被銷毀,也不會(huì)受影響志鞍。
1丑掺,service與Thread
參考自:https://blog.csdn.net/wei_chong_chong/article/details/52251193
1). Thread:Thread 是程序執(zhí)行的最小單元,它是分配CPU的基本單位述雾。thread是由本應(yīng)用程序托管
街州。可以用 Thread 來(lái)執(zhí)行一些異步的操作玻孟。可做耗時(shí)操作
唆缴。
2). Service:Service 是android的一種機(jī)制,系統(tǒng)的組件黍翎,它由系統(tǒng)進(jìn)程托管(servicemanager)
面徽。當(dāng)它運(yùn)行的時(shí)候如果是Local Service,那么對(duì)應(yīng)的 Service 是運(yùn)行在主進(jìn)程的 main 線程上的匣掸。如果是Remote Service趟紊,那么對(duì)應(yīng)的 Service 則是運(yùn)行在獨(dú)立進(jìn)程的 main 線程上。不可做耗時(shí)操作
碰酝,如果要做霎匈,service中添加Thread去做
Thread的使用
典型的應(yīng)用中,Thread可以在以下三個(gè)位置被創(chuàng)建送爸,不同的位置铛嘱,其生命周期不一樣,所以袭厂,我們應(yīng)該根據(jù)該Thread的目標(biāo)生命周期來(lái)決定是在Service中創(chuàng)建Thread還是在Activity中創(chuàng)建它墨吓。
(1) 在Activity中被創(chuàng)建
這種情況下,一般在onCreate時(shí)創(chuàng)建纹磺,在onDestroy()中銷毀帖烘,否則,Activity銷毀后橄杨,Thread是會(huì)依然在后臺(tái)運(yùn)行著秘症。
這種情況下,Thread的生命周期即為整個(gè)Activity的生命周期讥珍。所以历极,在Activity中創(chuàng)建的Thread只適合完成一些依賴Activity本身有關(guān)的任務(wù),比如定時(shí)更新一下Activity的控件狀態(tài)等
衷佃。
核心特點(diǎn):該Thread的就是為這個(gè)Activity服務(wù)的趟卸,完成這個(gè)特定的Activity交代的任務(wù),主動(dòng)通知該Activity一些消息和事件,Activity銷毀后锄列,該Thread也沒有存活的意義了图云。
(2)在Application中被創(chuàng)建
這種情況下,一般自定義Application類邻邮,重載onCreate方法竣况,并在其中創(chuàng)建Thread,當(dāng)然筒严,也會(huì)在onTerminate()方法中銷毀Thread丹泉,否則,如果Thread沒有退出的話鸭蛙,即使整個(gè)Application退出了摹恨,線程依然會(huì)在后臺(tái)運(yùn)行著。
這種情況下娶视,Thread的生命周期即為整個(gè)Application的生命周期晒哄。所以,在Application中創(chuàng)建的Thread肪获,可以執(zhí)行一些整個(gè)應(yīng)用級(jí)別的任務(wù)寝凌,比如定時(shí)檢查一下網(wǎng)絡(luò)連接狀態(tài)等等
。
核心特點(diǎn):該Thread的終極目標(biāo)是為這個(gè)APP的各個(gè)Activity服務(wù)的孝赫,包括完成某個(gè)Activity交代的任務(wù)较木,主動(dòng)通知某個(gè)Activity一些消息和事件等,APP退出之后該Thread也沒有存活的意義了寒锚。
以上這兩種情況下劫映,Thread的生命周期都不應(yīng)該超出整個(gè)應(yīng)用程序的生命周期,也就是刹前,整個(gè)APP退出之后,Thread都應(yīng)該完全退出雌桑,這樣才不會(huì)出現(xiàn)內(nèi)存泄漏或者僵尸線程喇喉。那么,如果你希望整個(gè)APP都退出之后依然能運(yùn)行該Thread校坑,那么就應(yīng)該把Thread放到Service中去創(chuàng)建和啟動(dòng)了拣技。
(3)在Service中被創(chuàng)建
這是保證最長(zhǎng)生命周期的Thread的唯一方式,只要整個(gè)Service不退出耍目,Thread就可以一直在后臺(tái)執(zhí)行膏斤,一般在Service的onCreate()中創(chuàng)建,在onDestroy()中銷毀邪驮。
所以莫辨,在Service中創(chuàng)建的Thread,適合長(zhǎng)期執(zhí)行一些獨(dú)立于APP的后臺(tái)任務(wù),比較常見的就是:在Service中保持與服務(wù)器端的長(zhǎng)連接
沮榜。
2盘榨,service啟動(dòng)
(1),startService
- 定義一個(gè)類繼承service
- 在manifest.xml文件中配置該service
- 使用context的startService(Intent)方法啟動(dòng)該service
- 不再使用時(shí)蟆融,調(diào)用stopService(Intent)方法停止該服務(wù)
- onCreate首次創(chuàng)建服務(wù)執(zhí)行草巡,onStartCommand方法每次重啟服務(wù)都會(huì)調(diào)用
(2),bindService
- 創(chuàng)建BindService服務(wù)端型酥,繼承自Service并在類中山憨,創(chuàng)建一個(gè)實(shí)現(xiàn)IBinder接口的實(shí)例對(duì)象并提供公共方法給客戶端調(diào)用;
- 從onBind()回調(diào)方法返回此Binder實(shí)例弥喉;
- 在客戶端中萍歉,從onServiceConnected()回調(diào)方法中接收Binder,并使用提供的方法調(diào)用綁定服務(wù)
- 多個(gè)activity可以綁定一個(gè)服務(wù)
- 綁定解除档桃,服務(wù)銷毀
四枪孩,BroadcastReceiver面試詳解
1,廣播定義
在android中藻肄,broadcast是一種廣泛運(yùn)用在應(yīng)用程序內(nèi)部或之間傳輸信息的機(jī)制蔑舞,Android中要發(fā)送的廣播內(nèi)容是一個(gè)Intent,這個(gè)Intent中可以攜帶我們要傳送的數(shù)據(jù)嘹屯。
2攻询,廣播使用場(chǎng)景
參考自:https://www.cnblogs.com/lwbqqyumidi/p/4168017.html
1.同一app內(nèi)部的同一組件內(nèi)的消息通信(單個(gè)或多個(gè)線程之間);(可用handler解決
)
2.同一app內(nèi)部的不同組件之間的消息通信(單個(gè)進(jìn)程)州弟;(可用EventBus
)
3.同一app具有多個(gè)進(jìn)程的不同組件之間的消息通信钧栖;
4.不同app之間的組件之間消息通信;
5.Android系統(tǒng)廣播在特定情況下與App之間的消息通信婆翔。
后三種常用廣播解決
3拯杠,廣播的種類
參考自:https://blog.csdn.net/carson_ho/article/details/53160580
- 普通廣播(Normal Broadcast)
- 系統(tǒng)廣播(System Broadcast)
- 有序廣播(Ordered Broadcast)
- 粘性廣播(Sticky Broadcast)
- App應(yīng)用內(nèi)廣播(Local Broadcast)
4,廣播的注冊(cè)
參考自:https://blog.csdn.net/u012702547/article/details/46955787
- 靜態(tài)注冊(cè):注冊(cè)完成就一直運(yùn)行
- 動(dòng)態(tài)注冊(cè):跟隨activity的生命周期
5啃奴,內(nèi)部實(shí)現(xiàn)機(jī)制
(1)潭陪,自定義廣播接收器BroadcastReceiver,并復(fù)寫onReceive方法
(2)最蕾,通過Binder機(jī)制向AMS(Activity Manager Service
)進(jìn)行注冊(cè)
(3)依溯,廣播發(fā)送者通過Binder機(jī)制向AMS發(fā)送廣播
(4),AMS查找符合相應(yīng)條件(IntentFilter/Permission等)的BroadcastReceiver瘟则,將廣播發(fā)送到BroadcastReceiver(一般是activity)相應(yīng)的消息循環(huán)隊(duì)列中
(5)黎炉,消息循環(huán)執(zhí)行,拿到此廣播醋拧,回調(diào)BroadcastReceiver的onReceive方法
6慷嗜,LocalBroadcastManager詳解
具體說明 https://blog.csdn.net/carson_ho/article/details/53160580
- 高效性淀弹,比系統(tǒng)的全局廣播更高效
- 安全性,只在自身app內(nèi)傳播洪添,不必?fù)?dān)心信息泄露
源碼分析
- LocalBroadcastManager高效的原因主要是因?yàn)閮?nèi)部是通過Handler發(fā)送message實(shí)現(xiàn)的垦页,它的sendBroadcast方法含義和我們平時(shí)所用的不一樣。
- 既然是Handler實(shí)現(xiàn)的干奢,所以相比系統(tǒng)廣播通過Binder實(shí)現(xiàn)更高效痊焊,同時(shí)使用Handler實(shí)現(xiàn),也使廣播控制在應(yīng)用內(nèi)部忿峻,不會(huì)發(fā)出去也不會(huì)被攻擊薄啥。
- LocalBroadcastManager內(nèi)部協(xié)作主要是靠這兩個(gè)Map集合:mReceivers和mActions,當(dāng)然還有一個(gè)List集合mPendingBroadcasts逛尚,這個(gè)主要是存儲(chǔ)待接收的廣播對(duì)象