Android有兩種主要的機(jī)制來處理低內(nèi)存的情況:內(nèi)核交換守護(hù)進(jìn)程(kernel swap daemon)和低內(nèi)存殺手(low-memory killer)。
讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長期合作伙伴,公司提供的服務(wù)項(xiàng)目有:空間域名、網(wǎng)站空間、營銷軟件、網(wǎng)站建設(shè)、羅莊網(wǎng)站維護(hù)、網(wǎng)站推廣。
比如,你的內(nèi)存是8G,如果每次使用完某個(gè)進(jìn)程就殺掉,那么被使用的內(nèi)存基本上會始終保持在某個(gè)值,比如4G以內(nèi),那么內(nèi)存的使用率就總是保存在50%以內(nèi),剩余的4G內(nèi)存形同虛設(shè),發(fā)揮用處的機(jī)會非常少。
線程池中的核心線程數(shù),默認(rèn)情況下核心線程會在線程池中一直存活,即使他們處于閑置狀態(tài)。
首先要說一點(diǎn),就是在Android中線程數(shù)超過一定量,也會拋出OOM,所以O(shè)OM不一定是內(nèi)存不足了才會拋出OOM。
在Android中線程池就是ThreadPoolExecutor對象。我們先來看一下ThreadPoolExecutor的構(gòu)造函數(shù)。
android內(nèi)存不夠了,會觸發(fā)oom機(jī)制,lowMemoryKiller會根據(jù)每個(gè)進(jìn)程的oom_adj的等級,依次殺死進(jìn)程,釋放內(nèi)存。lom會根據(jù)free的內(nèi)存的值,來判斷kill掉哪個(gè)等級下的進(jìn)程。例如當(dāng)空閑內(nèi)存只有64M了。
默認(rèn)的,所有的組件和程序運(yùn)行在這個(gè)進(jìn)程和線程中,也可以安排組件在其他的進(jìn)程或者線程中運(yùn)行。進(jìn)程:組件運(yùn)行的進(jìn)程由manifest file控制。組件的節(jié)點(diǎn)activity, service, receiver, 和 provider 都包含一個(gè) process 屬性。
線程是進(jìn)程的一個(gè)實(shí)體,是CPU調(diào)度和分派的基本單位,它是比進(jìn)程更小的能獨(dú)立運(yùn)行的基本單位。在Android中,線程會有那么幾種狀態(tài):創(chuàng)建、就緒、運(yùn)行、阻塞、結(jié)束。當(dāng)應(yīng)用程序有組件在運(yùn)行時(shí),UI線程是處于運(yùn)行狀態(tài)的。
所有的組件都在特定進(jìn)程的主線程中實(shí)例化,且系統(tǒng)調(diào)用組件是由主線程派遣。不會為每個(gè)實(shí)例創(chuàng)建單獨(dú)的線程,因此,對應(yīng)這些調(diào)用的方法——諸如View.onKeyDown()報(bào)告用用戶的行為和生命周期通知,總是運(yùn)行在進(jìn)程的主線程中。
通過4大組件啟動進(jìn)程時(shí),首先會完成app進(jìn)程的創(chuàng)建,app進(jìn)程創(chuàng)建完畢后會完成app進(jìn)程與system_server中的ActivityManagerService的相互綁定(AMP.attachApplication、ATP.bindApplication)。這兩個(gè)方法是通過Binder完成跨進(jìn)程通訊。
線程則負(fù)責(zé)協(xié)調(diào)執(zhí)行路徑和分配資源,以實(shí)現(xiàn)應(yīng)用程序的高效執(zhí)行??傊?,進(jìn)程和線程都是Android操作系統(tǒng)中的重要概念,它們之間的關(guān)系和區(qū)別都是開發(fā)過程中必須掌握的知識。
常用的單例模式有:餓漢模式、懶漢模式、雙重鎖懶漢模式、靜態(tài)內(nèi)部類模式、枚舉模式,我們來逐個(gè)解釋這些模式的區(qū)別。
單例模式,是一種常用的軟件設(shè)計(jì)模式。在它的核心結(jié)構(gòu)中只包含一個(gè)被稱為單例的特殊類。通過單例模式可以保證系統(tǒng)中,應(yīng)用該模式的類一個(gè)類只有一個(gè)實(shí)例。即一個(gè)類只有一個(gè)對象實(shí)例。
Builder模式:比如AlertDialog.Builder。適配器模式:比如GridView、ListView與Adapter。命令模式:比如Handler.post。享元模式:比如Message.obtain。單例模式:比如InputMethodManager.getInstance。觀察者模式:比如ContentObserver。
android service不存在單列的問題,service是安卓一個(gè)組件。單例是一種設(shè)計(jì)模式。在實(shí)際運(yùn)行中同樣的Service的確只能有一個(gè)。Service類沒有必要運(yùn)用單例模式。
Android 中的使用 在日常的Android開發(fā)中,也可以見到單例模式的身影。Glide 使用Glide加載圖片非常方便,大家應(yīng)該不陌生,可以看一下它的源碼中單例模式的實(shí)現(xiàn)方式。
在子線程的狀態(tài)發(fā)生變化時(shí),我們需要更新UI。
我們都知道Android是單線程模型,這意味著Android UI操作并不是線程安全的并且這些操作必須在UI線程中執(zhí)行,所以你單純的new一個(gè)Thrad并且start()不行的,因?yàn)檫@違背了Android的單線程模型。
Android應(yīng)用程序的代碼想在Android設(shè)備上運(yùn)行,要先進(jìn)行編譯,被打包成為一個(gè)被Android系統(tǒng)所能識別的文件才可以被運(yùn)行,而這種能被Android系統(tǒng)識別并運(yùn)行的文件格式便是APK。
Android中進(jìn)程與進(jìn)程、線程與線程之間如何通信?1)一個(gè) Android 程序開始運(yùn)行時(shí),會單獨(dú)啟動一個(gè)Process。默認(rèn)情況下,所有這個(gè)程序中的Activity或者Service都會跑在這個(gè)Process。
TimerTask運(yùn)行在一個(gè)單獨(dú)的線程里,而不是UI線程。所以使用 Android timer時(shí),注意android的單線程原則,確保線程安全。不要在TimerTask的run方法中做UI相關(guān)的操作,如:TextView.setText()等,這樣可能會導(dǎo)致UI線程阻塞。
安卓手機(jī)解鎖忘記密碼,首先要長按電源鍵進(jìn)行關(guān)機(jī),其次長按音量上鍵和關(guān)機(jī)鍵幾秒進(jìn)入恢復(fù)模式。清除格式化數(shù)據(jù)即可。Android是一種以Linux為基礎(chǔ)的開放源代碼操作系統(tǒng),主要使用于便攜設(shè)備。
線程在代碼是使用標(biāo)準(zhǔn)的java Thread對象來建立,那么在Android系統(tǒng)中提供了一系列方便的類來管理線程——Looper用來在一個(gè)線程中執(zhí)行消息循環(huán),Handler用來處理消息,HandlerThread創(chuàng)建帶有消息循環(huán)的線程。具體可以看下面的詳細(xì)介紹。
線程是進(jìn)程的一個(gè)實(shí)體,是CPU調(diào)度和分派的基本單位,它是比進(jìn)程更小的能獨(dú)立運(yùn)行的基本單位。線程比進(jìn)程更小,基本上不擁有系統(tǒng)資源,故對它的調(diào)度所用資源小,能更高效的提高系統(tǒng)內(nèi)多個(gè)程序間并發(fā)執(zhí)行的。
如Android會傾向于關(guān)閉一個(gè)長期不顯示在界面的進(jìn)程來支持一個(gè)經(jīng)常顯示在界面的進(jìn)程。線程:即使為組件分配了不同的進(jìn)程,有時(shí)候也需要再分配線程。
android中的進(jìn)程就是一個(gè)個(gè)獨(dú)立的APP應(yīng)用。
不同包名的組件可以一定的方式運(yùn)行在同一個(gè)進(jìn)程中。一個(gè)Activity啟動后,至少會有3個(gè)線程。一個(gè)主線程和2個(gè)binder線程。
1、Android 中線程可分為 主線程 和 子線程 兩類,其中主線程也就是 UI線程 ,它的主要這作用就是運(yùn)行四大組件、處理界面交互。子線程則主要是處理耗時(shí)任務(wù),也是我們要重點(diǎn)分析的。
2、在Android中有主線程和子線程的區(qū)分。主線程又稱為UI線程,主要是處理一些和界面相關(guān)的事情,而子線程主要是用于處理一些耗時(shí)比較大的一些任務(wù),例如一些網(wǎng)絡(luò)操作,IO請求等。
3、對Activity 來說 UI線程就是其主線程 對View來說 UI線程就是創(chuàng)建ViewRootImpl所在的線程 可以通過 WindowManager 內(nèi)部會創(chuàng)建ViewRootImpl對象 好了,進(jìn)入主題。我們來慢慢揭開面紗。
4、UI線程,即主線程,在主線程里不能進(jìn)行耗時(shí)的操作,不然系統(tǒng)會彈出ANR提示框,所以一般的耗時(shí)操作都是放到非UI線程里去完成,即子線程。目前在開發(fā)層面的區(qū)別應(yīng)該主要是這個(gè)吧,其它的暫時(shí)沒聽說。
5、線程:UIthread 通常就是main thread,而Android啟動程序時(shí)會替它建立一個(gè)MessageQueue。Handler創(chuàng)建消息 每一個(gè)消息都需要被指定的Handler處理,通過Handler創(chuàng)建消息便可以完成此功能。Android消息機(jī)制中引入了消息池。
6、例如進(jìn)行網(wǎng)絡(luò)操作時(shí)或是更新UI時(shí),如果運(yùn)行時(shí)間較長,就不能直接在主線程中運(yùn)行,因?yàn)檫@樣會阻塞這個(gè)進(jìn)程中其他的組件,我們可以將這樣的組件分配到新建的線程中或是其他的線程中運(yùn)行。