在工作中有不少朋友聯(lián)系我,問我有沒有相關(guān)推薦的書或者資料可以學(xué)習(xí)的。
自己也在不斷的學(xué)習(xí)和提升,所以再這些過程中吧遇到的面試題整理成了一份983頁的PDF公司主營業(yè)務(wù):網(wǎng)站設(shè)計、做網(wǎng)站、移動網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。創(chuàng)新互聯(lián)是一支青春激揚、勤奮敬業(yè)、活力青春激揚、勤奮敬業(yè)、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴謹、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)推出成安免費做網(wǎng)站回饋大家。
(更多完整項目下載。未完待續(xù)。源碼。圖文知識后續(xù)上傳github。)
可以點擊關(guān)于我聯(lián)系我獲取完整PDF
(VX:×××)
1)Handler線程的消息通訊的橋梁,主要用來發(fā)送消息及處理消息。
2)Thread普通線程,如果需要有自己的消息隊列,需要調(diào)用Looper.prepare()
創(chuàng)建Looper
實例,調(diào)用loop()去循環(huán)消息。
3)HandlerThread
是一個帶有Looper
的線程,在HandleThread
的run()方法中調(diào)用了Looper.prepare()
創(chuàng)建了Looper
實例,并調(diào)用Looper.loop()
開啟了Loop循環(huán),循環(huán)從消息隊列中獲取消息并交由Handler處理。利用該線程的Looper
創(chuàng)建Handler實例,此Handler的handleMessage()
方法是運行在子線程中的。即Handler利用哪個線程的Looper
創(chuàng)建的實例,它就和相應(yīng)的線程綁定到一起,處理該線程上的消息,它的handleMessage()
方法就是在那個線程中運行的,無參構(gòu)造默認是主線程。
HandlerThread
提供了quit()
/quitSafely()
方法退出HandlerThread
的消息循環(huán),它們分別調(diào)用Looper
的quit和quitSafely
方法,quit會將消息隊列中的所有消息移除,而quitSafely
會將消息隊列所有延遲消息移除,非延遲消息派發(fā)出去讓Handler去處理。
HandlerThread
適合處理本地IO讀寫操作(讀寫數(shù)據(jù)庫或文件),因為本地IO操作耗時不長,對于單線程+異步隊列不會產(chǎn)生較大阻塞,而網(wǎng)絡(luò)操作相對比較耗時,容易阻塞后面的請求,因此HandlerThread
不適合加入網(wǎng)絡(luò)操作。
1)非靜態(tài)內(nèi)部類、匿名內(nèi)部類:非靜態(tài)內(nèi)部類、匿名內(nèi)部類 都會持有外部類的一個引用,如果有一個靜態(tài)變量引用了非靜態(tài)內(nèi)部類或者匿名內(nèi)部類,導(dǎo)致非靜態(tài)內(nèi)部類或者匿名內(nèi)部類的生命周期比外部類(Activity)長,就會導(dǎo)致外部類在該被回收的時候,無法被回收掉,引起內(nèi)存泄露, 除非外部類被卸載。
解決辦法:將非靜態(tài)內(nèi)部類、匿名內(nèi)部類 改成靜態(tài)內(nèi)部類,或者直接抽離成一個外部類。?如果在靜態(tài)內(nèi)部類中,需要引用外部類對象,那么可以將這個引用封裝在一個WeakReference
中。
2)靜態(tài)的View:當一個Activity經(jīng)常啟動,但是對應(yīng)的View讀取非常耗時,我們可以通過靜態(tài)View變量來保持對該Activity的rootView
引用。這樣就可以不用每次啟動Activity都去讀取并渲染View了。但View attach到我們的Window上,就會持有一個Context(即Activity)的引用。而我們的View有事一個靜態(tài)變量,所以導(dǎo)致Activity不被回收。
解決辦法:?在使用靜態(tài)View時,需要確保在資源回收時,將靜態(tài)View detach掉。
3)Handler:在Activity中定義Handler對象,那么Handler持有Activty
的引用。而每個Message對象是持有Handler的引用的(Message對象的target屬性持有Handler引用),從而導(dǎo)致Message間接引用到了Activity。如果在Activty destroy
之后,消息隊列中還有Message對象,Activty
是不會被回收的。
解決辦法:?將Handler放入單獨的類或者將Handler放入到靜態(tài)內(nèi)部類中(靜態(tài)內(nèi)部類不會持有外部類的引用)。如果想要在handler內(nèi)部去調(diào)用所在的外部類Activity,可以在handler內(nèi)部使用弱引用的方式指向所在Activity,在onDestory
時,調(diào)用相應(yīng)的方法移除回調(diào)和刪除消息。
4)監(jiān)聽器(各種需要注冊的Listener,Watcher等):當我們需要使用系統(tǒng)服務(wù)時,比如執(zhí)行某些后臺任務(wù)、為硬件訪問提供接口等等系統(tǒng)服務(wù)。我們需要把自己注冊到服務(wù)的監(jiān)聽器中。然而,這會讓服務(wù)持有 activity 的引用,如果程序員忘記在 activity 銷毀時取消注冊,那就會導(dǎo)致 activity 泄漏了。
解決辦法:在onDestory
中移除注冊
5)資源對象沒關(guān)閉造成內(nèi)存泄漏:當我們打開資源時,一般都會使用緩存。比如讀寫文件資源、打開數(shù)據(jù)庫資源、使用Bitmap資源等等。當我們不再使用時,應(yīng)該關(guān)閉它們,使得緩存內(nèi)存區(qū)域及時回收。
解決辦法:使用try finally結(jié)合,在try塊中打開資源,在finally中關(guān)閉資源
6)屬性動畫:在使用ValueAnimator
或者ObjectAnimator
時,如果沒有及時做cancel取消動畫,就可能造成內(nèi)存泄露。因為在cancel方法里,最后調(diào)用了endAnimation()
; ,在endAnimation
里,有個AnimationHandler
的單例,會持有屬性動畫對象的引用。
解決辦法:在onDestory
中調(diào)用動畫的cancel方法
7)RxJava
:在使用RxJava
時,如果在發(fā)布了一個訂閱后,由于沒有及時取消,導(dǎo)致Activity
/Fragment
無法銷毀,導(dǎo)致的內(nèi)存泄露。
解決辦法:使用RxLifeCycle
1)內(nèi)存泄漏:指程序中已動態(tài)分配的堆內(nèi)存由于某種原因未釋放或無法釋放,造成系統(tǒng)內(nèi)存的浪費,導(dǎo)致程序運行速度減慢甚至系統(tǒng)奔潰等嚴重后果。
2)一次內(nèi)存泄漏似乎不會有大的影響,但內(nèi)存泄漏后堆積的結(jié)果就是內(nèi)存溢出。
3)內(nèi)存泄漏具有隱蔽性,積累性的特征,比其他內(nèi)存非法訪問錯誤更難檢測。這是因為內(nèi)存泄漏產(chǎn)生的原因是內(nèi)存塊未被釋放,屬于遺漏型缺陷而不是過錯型缺陷。此外,內(nèi)存泄漏不會直接產(chǎn)生可觀察的錯誤,而是逐漸積累,降低系統(tǒng)的整體性性能。
4)如何有效的進行內(nèi)存分配和釋放,防止內(nèi)存泄漏,是軟件開發(fā)人員的關(guān)鍵問題,比如一個服務(wù)器應(yīng)用軟件要長時間服務(wù)多個客戶端,若存在內(nèi)存泄漏,則會逐漸堆積,導(dǎo)致一系列嚴重后果。
指程序在申請內(nèi)存時,沒有足夠的內(nèi)存供申請者使用,或者說,給了你一塊存儲int類型數(shù)據(jù)的存儲空間,但是你卻存儲long類型的數(shù)據(jù),就會導(dǎo)致內(nèi)存不夠用,報錯OOM
,即出現(xiàn)內(nèi)存溢出的錯誤。
LruCache
默認緩存大小ContentProvider
的權(quán)限管理(解答:讀寫分離,權(quán)限控制-精確到表級,URL控制)anr
的時間限制是多少?ListView
重用的是什么?Parcelable
?Parcelable
的使用?所有的答案,請查看完整的PDF版
(更多完整項目下載。未完待續(xù)。源碼。圖文知識后續(xù)上傳github。)
可以點擊關(guān)于我聯(lián)系我獲取完整PDF
(VX:×××)