1铆遭、fragment
fragment切換
使用
commitAllowingStateLoss()
方法進行commit()
commit
和commitAllowingStateLoss
的異同點:
1硝桩、commitAllowingStateLoss
該方法的注釋:
allows the commit to be executed after an activity's state is saved. This is dangerous because the commit can be lost if the activity needs to later be restored from its state, so this should only be used for cases where it is okay for the UI state to change unexpectedly on the user.
可見該方法不會在activity或者fragment的onSaveInstanceState
之后執(zhí)行,使用了該方法枚荣,可能再restore之后碗脊,不會有之前的狀態(tài)。
用處場景:注釋中說道橄妆,可以對于用戶而言不可見衙伶,用戶可能不知道到底fragment的切換發(fā)生了什么。
比方說:接收到一個推送害碾,然后發(fā)送一個切換某個界面frament的操作矢劲。如果該UI不是可見的,那么建議使用該方法慌随。
2芬沉、fragment中使用replace
還是hide
replace會執(zhí)行銷毀該fragment并重新創(chuàng)建的操作,但是hide則不會
hide后阁猜,覆蓋在上層的fragment可能仍舊會觸發(fā)下層fragment的點擊操作什么的丸逸。
Notification
1、notification版本的兼容
對api 15以下蹦漠,18以上需要對notification做出兼容的處理椭员。
service
1、基本介紹
The Android system will force-stop a service only when memory is low and it must recover system resources for the activity that has user focus.
一個service**只有**
在Android系統(tǒng)的內(nèi)存不夠時才會強制停止笛园,并且會將前臺可見的activity的系統(tǒng)資源進行恢復(fù)隘击。
If the service is bound to an activity that has user focus, then it's less likely to be killed, and if the service is declared to run in the foreground (discussed later), then it will almost never be killed.
如果service是bind的話,那么該service會可能性較小的被殺掉研铆;如果service被聲明為foreground(前臺)的埋同,那么該service基本上不會被系統(tǒng)殺掉。
但是棵红,換言之凶赁,如果是started,并且是long-running的(長時間運行的)逆甜,那么虱肄,隨著時間的推移,該service被系統(tǒng)回收的概率會隨時間增長而增大交煞。
如果你的service是start的話咏窿,那么可能需要設(shè)計成間歇性的被系統(tǒng)重新啟動。
被殺的話素征,系統(tǒng)會根據(jù)onStartCommand返回的值集嵌,在系統(tǒng)資源重新可用的情況進行重新啟動該服務(wù)。
2御毅、進程和線程(關(guān)于service何時可能會被系統(tǒng)回收)
正常情況下根欧,android系統(tǒng)會為該application啟動一個新的Linux進程和一個(single)處理的線程。這樣端蛆,默認的情況下就是:該application中所有的components將會運行在這個進程和線程中(我們稱之為main線程)凤粗,如果一個component被啟動了,并且該app早已經(jīng)有了一個linux進程今豆,那么該component將會運行在該繼承的默認線程上侈沪。當(dāng)然,我們也能為該app中不同的component指定不同的進程晚凿,并且在同一進程指定不同的線程亭罪。
在manifest中的不同組件<activity>,<service>歼秽,<receiver>和<provider>中使用andorid:process
進行該組件的進程的指定应役,這樣,指定了相同進程的組件將會想用同一個linux用戶ID燥筷,并且使用了想用的certificate進行指定箩祥。
<application>同樣支持android:process
屬性,設(shè)定的話肆氓,所有的組件將會運行在相同的進程中袍祖。
進程會被系統(tǒng)殺,判斷的標(biāo)準(zhǔn)是:
當(dāng)android系統(tǒng)準(zhǔn)備殺掉一個進程的時候谢揪,會對所有的進程考量他們對于用戶的重要性蕉陋。舉例而言捐凭,會更傾向于殺掉那些activity不可見的進程。
考量進程的重要性的依據(jù)就是:
進程的生命周期
Android系統(tǒng)會盡量保證一個進程在系統(tǒng)中存在足夠長的時間凳鬓,但是不可避免的就是茁肠,當(dāng)系統(tǒng)資源不夠時,新建出一個進程就需要kill掉老的進程保證新的進程有足夠的資源使用缩举。
android系統(tǒng)會基于垦梆,********進程中運行的****components****已以及****components****的狀態(tài)********,將每個進程放進系統(tǒng)的“importance hierarchy”中仅孩,這樣托猩,在系統(tǒng)資源不夠時,具有最低重要性的進程會被殺死辽慕,依次類推京腥,進行系統(tǒng)資源的回收。
importance hierarchy中五種進程等級
1鼻百、Foreground Process
用戶正在doing的進程绞旅,符合以下任一條件的都是:
- 一個正在和用戶交互的activity,該activity已經(jīng)調(diào)用了
onResume
方法温艇; - 一個已經(jīng)綁定了service的activity因悲,并且該activity正在和用戶交互;
- 調(diào)用了
startForeground
的service勺爱; - 正在執(zhí)行service中的
onCreate
晃琳,onStart
,onDestroy
方法的service琐鲁; - 具有一個正在執(zhí)行
onReceive()
方法的BroadCastReceiver
通常而言卫旱,在特定的情況下,只有少數(shù)的Foreground進程正在運行围段,他們只有在系統(tǒng)使出渾身解數(shù)之后顾翼,系統(tǒng)資源還不能滿足正常的android進程時,才會殺掉他們奈泪,以保證用戶UI響應(yīng)正常适贸。
2、Visible Process
該進程不包括任何的前臺組件(foreground components)涝桅,但是仍舊能夠影響到用戶在屏幕上可見的內(nèi)容拜姿。
符合以下兩種情況之一的就是就可以認為是Visible Process
。
- activity已經(jīng)走了
onPause()
方法冯遂,但是該activity仍舊希望能夠和該用戶進行交互蕊肥。比方說一個activity上面覆蓋一個Dialog; - 該進程擁有一個前臺(foreground)或者可見(visiable)的activity綁定在一起蛤肌。
一個visiable process被看做是非常重要的(extremely important)壁却,只有在foreground process得不到正常運行的時候批狱,才會選擇殺掉visiable process。
3儒洛、Service Process
該進程運行一個使用startService()
方法的進程精耐,并且不符合上面兩種更高優(yōu)先級的進程的條件狼速。
盡管Service Process不會和用戶的UI進行交互琅锻,但是他仍舊在執(zhí)行一些重要的操作,比如說:播放音樂向胡,下載任務(wù)等等恼蓬。
4、Background Process
一個持有已經(jīng)執(zhí)行了activity的onDestroy()
方法的process僵芹。
該進行不和用戶做任何的交互处硬,系統(tǒng)可以隨時殺掉這些進程。
這些進程會放置在LRU中拇派,以保證用戶最先看到的被第系統(tǒng)首先殺掉荷辕。
如果使用者能夠很好的實現(xiàn)activity的聲明周期,那么在該進程被殺死的情況下件豌,用戶重新進入activity后疮方,系統(tǒng)會restore改activity之前保存的若干狀態(tài),這樣茧彤,用戶的體驗無細致性的差異骡显。
5、Empty Process
該進程不擁有任何active的application components曾掂。
該種進程存在的唯一目的就是為了caching惫谤,為了方便在下一次較快的啟動一個component。
系統(tǒng)經(jīng)常殺掉這些進程為了能夠:平衡進程cache和underlying kernel caches的過載系統(tǒng)資源珠洗。
android系統(tǒng)傾向于將一個進程的評級向高處評價溜歪,比方說,一個擁有service和和一個active activity许蓖,那么android系統(tǒng)將會將該進程評價為Visible Processe而非一個service process蝴猪。
進程的優(yōu)先級會不斷的變化,一個服務(wù)于B進程的A進程的評級不可能比B等價低蛔糯,至少一樣拯腮。
基于這種進程依賴性,在某些場景下非常有用:
一個需要開啟了長時間任務(wù)的activity可以開啟一個service進行任務(wù)的進行蚁飒,而非直接開啟一個線程动壤,這樣,該任務(wù)的進程等級就至少是service process
淮逻,這就是為了在廣播中使用service而非一個新的線程
來執(zhí)行耗時的操作琼懊。
3阁簸、線程(Thread)
android系統(tǒng)不會為每個組件創(chuàng)建一個新的線程,默認都在UIThread中執(zhí)行哼丈,并且每個component都從該UIThread中分發(fā)出去启妹。相應(yīng)的,各種系統(tǒng)的回調(diào)(system callbacks)都在UIThread中執(zhí)行醉旦。
這樣饶米,我們經(jīng)常說到的不能在UIThread中做一些耗時的操作是因為
- 耗時的操作可能會阻塞UIThread,這樣车胡,在等待了5秒之后檬输,程序就會ANR;
- UI tool kit是線程不安全的匈棘,這樣丧慈,你就不能在工作線程做UI的改變(因為可能有許多不同的工作線程)
兩點建議:
1、不要阻塞UI線程主卫;
2逃默、不要在非UI Thread中使用Android UI toolkit。
下面的幾種方法可以在工作線程中操作view在UI線程中工作:
Activity.runOnUIThread()
View.post()
View.postDelayed()