關(guān)于安卓面試題部分目前整理了兩篇:
安卓面試題 基礎(chǔ)篇
安卓面試題 進(jìn)階篇
Handler腹泌、Looper银酗、MessageQueue構(gòu)成的安卓消息機(jī)制
安卓消息機(jī)制是安卓面試中嘲茫考的知識(shí)點(diǎn)之一呻此,詳細(xì)解釋可以看以下這篇文章陈肛,更加全面的了解消息機(jī)制闻书。
http://www.reibang.com/p/b03d46809c4d
ThreadLocal作用以及原理?
ThreadLocal用于實(shí)現(xiàn)在不同的線程中存儲(chǔ)線程私有數(shù)據(jù)的類(lèi)涝影。在多線程的環(huán)境中,當(dāng)多個(gè)線程需要對(duì)某個(gè)變量進(jìn)行頻繁操作争占,同時(shí)各個(gè)線程間不需要同步燃逻。此時(shí),各個(gè)子線程只需要對(duì)存儲(chǔ)在當(dāng)前線程中的變量的拷貝進(jìn)行操作即可臂痕,程序的運(yùn)行效率會(huì)很高伯襟,即所謂的空間換時(shí)間。
原理:在當(dāng)前線程中調(diào)用get方法時(shí)握童,通過(guò)ThreadLocal的initialValue方法創(chuàng)建當(dāng)前線程的一個(gè)本地?cái)?shù)據(jù)拷貝姆怪,將此拷貝添加到當(dāng)前線程本地?cái)?shù)據(jù)的table數(shù)組當(dāng)中;或者在調(diào)用set方法時(shí)澡绩,將當(dāng)前線程的本地?cái)?shù)據(jù)存儲(chǔ)到當(dāng)前線程的table數(shù)組中.當(dāng)前線程通過(guò)調(diào)用ThreadLocal對(duì)象的get方法即得到當(dāng)前線程本地?cái)?shù)據(jù)對(duì)象稽揭。
請(qǐng)簡(jiǎn)要描述一下View事件傳遞分發(fā)機(jī)制
事件的傳遞順序 Activity -> Window -> View。
事件分發(fā)的關(guān)鍵函數(shù):
dispatchTouchEvent肥卡、onInterceptTouchEvent和onTouchEvent溪掀。
dispatchTouchEvent:用于事件的分發(fā),如果事件傳遞到View層級(jí)步鉴,則一定會(huì)調(diào)用此函數(shù)揪胃。函數(shù)的返回結(jié)果受當(dāng)前View的onTouchEvent方法和處于下一層級(jí)View的dispatchTouchEvent方法影響。
onInterceptTouchEvent:返回結(jié)果表示是否攔截此事件
onTouchEvent:用于處理事件氛琢,如果View決定攔截事件則在該函數(shù)中進(jìn)行事件處理喊递。
事件分發(fā)中的onTouch和onTouchEvent有什么區(qū)別,又該如何使用阳似?
onTouchListener的onTouch方法優(yōu)先級(jí)比onTouchEvent高骚勘,會(huì)先觸發(fā)。
若onTouch方法返回false則會(huì)接著觸發(fā)onTouchEvent撮奏,反之onTouchEvent方法不會(huì)被調(diào)用调鲸。
View和ViewGroup分別有哪些事件分發(fā)相關(guān)的回調(diào)方法
dispatchTouchEvent盛杰、onInterceptTouchEvent和onTouchEvent。
View繪制流程
onMeasure:測(cè)量視圖的大小藐石,從頂層父View到子View遞歸調(diào)用measure()方法即供,measure()調(diào)用onMeasure()方法,onMeasure()方法完成繪制工作于微。
onLayout:確定視圖的位置逗嫡,從頂層父View到子View遞歸調(diào)用layout()方法,父View將上一步measure()方法得到的子View的布局大小和布局參數(shù)株依,將子View放在合適的位置上驱证。
onDraw:繪制最終的視圖,首先ViewRoot創(chuàng)建一個(gè)Canvas對(duì)象恋腕,然后調(diào)用onDraw()方法進(jìn)行繪制抹锄。onDraw()方法的繪制流程為: 繪制視圖背景-> 繪制畫(huà)布的圖層->繪制View內(nèi)容->繪制子視圖。
自定義View
http://www.reibang.com/p/c84693096e41
AsyncTask機(jī)制
郭神出品
http://blog.csdn.net/guolin_blog/article/details/11711405
如何取消AsyncTask荠藤?
調(diào)用cancel方法伙单,傳遞信號(hào)量。同時(shí)哈肖,在doInBackground中檢測(cè)當(dāng)前狀態(tài):當(dāng)狀態(tài)是cancel狀態(tài)吻育,則立刻跳出循環(huán)。
為什么不能在子線程更新UI淤井?
安卓系統(tǒng)的UI控件并非線程安全的布疼,如果多線程并發(fā)訪問(wèn)同一個(gè)UI控件時(shí)會(huì)引發(fā)UI控件狀態(tài)的混亂。
ANR產(chǎn)生的原因是什么币狠?
ANR的全稱(chēng)是application not responding游两,意思就是程序未響應(yīng)。
產(chǎn)生原因:
1.主線程執(zhí)行了耗時(shí)操作漩绵,在一定時(shí)間內(nèi)沒(méi)有響應(yīng)操作器罐。比如數(shù)據(jù)庫(kù)操作或網(wǎng)絡(luò)編程。
2.其他進(jìn)程(就是其他程序)占用CPU導(dǎo)致本進(jìn)程得不到CPU時(shí)間片渐行,比如其他進(jìn)程的頻繁讀寫(xiě)操作可能會(huì)導(dǎo)致這個(gè)問(wèn)題轰坊。
ANR定位和修正
可以通過(guò)查看/data/anr/traces.txt查看ANR信息。根據(jù)日志文件的信息提示修改代碼祟印。
OOM是什么肴沫?
OOM,全稱(chēng)“Out Of Memory”蕴忆,翻譯為“內(nèi)存用盡”當(dāng)JVM因?yàn)闆](méi)有足夠的內(nèi)存來(lái)為對(duì)象分配空間并且垃圾回收器也已經(jīng)沒(méi)有空間可回收時(shí)颤芬,就會(huì)拋出OOM。
什么情況導(dǎo)致OOM?
OOM常見(jiàn)情況:
1)Acitivity沒(méi)有對(duì)棧進(jìn)行管理,如果開(kāi)啟過(guò)多,就容易造成內(nèi)存溢出
2)加載大的圖片或者同時(shí)數(shù)量過(guò)多的圖片的時(shí)候
3)程序存在內(nèi)存泄漏問(wèn)題站蝠,導(dǎo)致系統(tǒng)可用內(nèi)存越來(lái)越小汰具。
4)遞歸次數(shù)過(guò)多,也會(huì)導(dǎo)致內(nèi)存溢出.
5)頻繁的內(nèi)存抖動(dòng),也會(huì)造成OOM異常的發(fā)生,大量小的對(duì)象被頻繁的創(chuàng)建,導(dǎo)致內(nèi)存碎片,從而當(dāng)需要分配內(nèi)存的時(shí)候,雖然總體上還有內(nèi)存分配,但是由于這些內(nèi)存不是連續(xù)的,導(dǎo)致無(wú)法分配,系統(tǒng)就直接返回OOM了
有什么解決方法可以避免OOM?
1)減小對(duì)象的內(nèi)存占用菱魔,避免OOM的第一步就是要盡量減少新分配出來(lái)的對(duì)象占用內(nèi)存的大小留荔,盡量使用更加輕量的對(duì)象。
2)內(nèi)存對(duì)象的重復(fù)利用澜倦,大多數(shù)對(duì)象的復(fù)用聚蝶,最終實(shí)施的方案都是利用對(duì)象池技術(shù),要么是在編寫(xiě)代碼時(shí)顯式地在程序里創(chuàng)建對(duì)象池藻治,然后處理好復(fù)用的實(shí)現(xiàn)邏輯碘勉。要么就是利用系統(tǒng)框架既有的某些復(fù)用特性,減少對(duì)象的重復(fù)創(chuàng)建桩卵,從而降低內(nèi)存的分配與回收验靡。
3)避免對(duì)象的內(nèi)存泄露,內(nèi)存對(duì)象的泄漏雏节,會(huì)導(dǎo)致一些不再使用的對(duì)象無(wú)法及時(shí)釋放胜嗓,這樣一方面占用了寶貴的內(nèi)存空間,很容易導(dǎo)致后續(xù)需要分 配內(nèi)存的時(shí)候矾屯,空閑空間不足而出現(xiàn)OOM。
4)內(nèi)存使用策略?xún)?yōu)化初厚。
OOM是否可以try catch件蚕?為什么?
可以产禾。在某些情況下排作,我們需要事先評(píng)估那些可能發(fā)生OOM的代碼,對(duì)于這些可能發(fā)生OOM的代碼亚情,加入catch機(jī)制妄痪,可以考慮在catch里面嘗試一次降級(jí)的內(nèi)存分配操作。
內(nèi)存泄漏是什么楞件?
內(nèi)存泄漏(Memory Leak)是指程序中己動(dòng)態(tài)分配的堆內(nèi)存由于某種原因程序未釋放或無(wú)法釋放衫生,造成系統(tǒng)內(nèi)存的浪費(fèi),導(dǎo)致程序運(yùn)行速度減慢甚至系統(tǒng)崩潰等嚴(yán)重后果土浸。
什么情況導(dǎo)致內(nèi)存泄漏罪针?
常見(jiàn)情況:
1)單例造成的內(nèi)存泄漏
由于單例的靜態(tài)特性使得其生命周期和應(yīng)用的生命周期一樣長(zhǎng),如果一個(gè)對(duì)象已經(jīng)不再需要使用了黄伊,而單例對(duì)象還持有該對(duì)象的引用泪酱,就會(huì)使得該對(duì)象不能被正常回收,從而導(dǎo)致了內(nèi)存泄漏墓阀。
2)非靜態(tài)內(nèi)部類(lèi)創(chuàng)建靜態(tài)實(shí)例造成的內(nèi)存泄漏
3)Handler造成的內(nèi)存泄漏
當(dāng)Activity結(jié)束時(shí)毡惜,未處理的消息持有handler的引用,而handler又持有它所屬的外部類(lèi)也就是MainActivity的引用斯撮。這條引用關(guān)系會(huì)一直保持直到消息得到處理经伙,這樣阻止了MainActivity被垃圾回收器回收,從而造成了內(nèi)存泄漏吮成。
4)線程造成的內(nèi)存泄漏
若線程持有Activity的引用橱乱,且線程處于后臺(tái)執(zhí)行狀態(tài),當(dāng)Activity銷(xiāo)毀但線程仍然存活且持有Activity的引用粱甫,則會(huì)引起內(nèi)存泄漏泳叠。
5)資源未關(guān)閉造成的內(nèi)存泄漏
對(duì)于使用了BraodcastReceiver,ContentObserver茶宵,F(xiàn)ile危纫,Cursor,Stream乌庶,Bitmap等資源种蝶,應(yīng)該在Activity銷(xiāo)毀時(shí)及時(shí)關(guān)閉或者注銷(xiāo),否則這些資源將不會(huì)被回收瞒大,從而造成內(nèi)存泄漏螃征。
6)使用ListView時(shí)造成的內(nèi)存泄漏
初始時(shí)ListView會(huì)從BaseAdapter中根據(jù)當(dāng)前的屏幕布局實(shí)例化一定數(shù)量的View對(duì)象,同時(shí)ListView會(huì)將這些View對(duì)象緩存起來(lái)透敌。當(dāng)向上滾動(dòng)ListView時(shí)盯滚,原先位于最上面的Item的View對(duì)象會(huì)被回收,然后被用來(lái)構(gòu)造新出現(xiàn)在下面的Item酗电。這個(gè)構(gòu)造過(guò)程就是由getView()方法完成的魄藕,getView()的第二個(gè)形參convertView就是被緩存起來(lái)的Item的View對(duì)象(初始化時(shí)緩存中沒(méi)有View對(duì)象則convertView是null)。構(gòu)造Adapter時(shí)撵术,沒(méi)有使用緩存的convertView背率。
7)集合容器中的內(nèi)存泄露
我們通常把一些對(duì)象的引用加入到了集合容器(比如ArrayList)中,當(dāng)我們不需要該對(duì)象時(shí)嫩与,并沒(méi)有把它的引用從集合中清理掉寝姿,這樣這個(gè)集合就會(huì)越來(lái)越大。如果這個(gè)集合是static的話划滋,那情況就更嚴(yán)重了会油。
8)WebView造成的泄露
當(dāng)我們不要使用WebView對(duì)象時(shí),應(yīng)該調(diào)用它的destory()函數(shù)來(lái)銷(xiāo)毀它古毛,并釋放其占用的內(nèi)存翻翩,否則其長(zhǎng)期占用的內(nèi)存也不能被回收都许,從而造成內(nèi)存泄露。
如何防止內(nèi)存泄漏嫂冻?
1)在涉及使用Context時(shí)胶征,對(duì)于生命周期比Activity長(zhǎng)的對(duì)象應(yīng)該使用Application的Context。凡是使用Context優(yōu)先考慮Application的Context桨仿,當(dāng)然它并不是萬(wàn)能的睛低,對(duì)于有些地方則必須使用Activity的Context。
2)對(duì)于需要在靜態(tài)內(nèi)部類(lèi)中使用非靜態(tài)外部成員變量(例如:Context服傍、View )钱雷,可以在靜態(tài)內(nèi)部類(lèi)中使用弱引用來(lái)引用外部類(lèi)的變量來(lái)避免內(nèi)存泄漏。
3)對(duì)于不再需要使用的對(duì)象吹零,顯示的將其賦值為null罩抗,比如使用完Bitmap后先調(diào)用recycle(),再賦為null灿椅。
4)保持對(duì)對(duì)象生命周期的敏感套蒂,特別注意單例、靜態(tài)對(duì)象茫蛹、全局性集合等的生命周期操刀。
5)對(duì)于生命周期比Activity長(zhǎng)的內(nèi)部類(lèi)對(duì)象,并且內(nèi)部類(lèi)中使用了外部類(lèi)的成員變量婴洼,可以采用以下方式避免內(nèi)存泄漏:
① 將內(nèi)部類(lèi)改為靜態(tài)內(nèi)部類(lèi)
② 靜態(tài)內(nèi)部類(lèi)中使用弱引用來(lái)引用外部類(lèi)的成員變量
內(nèi)存泄漏和內(nèi)存溢出區(qū)別骨坑?
內(nèi)存泄漏:主要是因?yàn)槌绦虼嬖贐UG 導(dǎo)致內(nèi)存沒(méi)有釋放 。
內(nèi)存溢出:是指內(nèi)存不夠用了柬采,導(dǎo)致不夠用的原因很多欢唾,內(nèi)存泄漏是導(dǎo)致內(nèi)存溢出原因一種。
LruCache默認(rèn)緩存大小
LruCache默認(rèn)緩存大小是當(dāng)前操作系統(tǒng)分配給該進(jìn)程的內(nèi)存的1/8警没。
廣播是否可以請(qǐng)求網(wǎng)絡(luò)匈辱?
從4.0 開(kāi)始所有的網(wǎng)絡(luò)請(qǐng)求都需要在線程中振湾,廣播請(qǐng)求網(wǎng)絡(luò)同理 開(kāi)啟線程在線程中請(qǐng)求網(wǎng)絡(luò)
廣播引起anr的時(shí)間限制是多少杀迹?
Activity----->5秒
BroadcastReceiver----->10秒
Service----->20秒
Android為什么引入Parcelable?
Java提供了Serializable接口方式實(shí)現(xiàn)序列化押搪,但這種方式效率較低树酪。因此,安卓提供Parcelable接口以實(shí)現(xiàn)更加高效的序列化方式大州。
簡(jiǎn)述一下NDK
NDK(Native Development Kit)是Android的一個(gè)工具開(kāi)發(fā)包续语。
NDK的目的是快速開(kāi)發(fā)C、C++的動(dòng)態(tài)庫(kù)厦画,并自動(dòng)將so和應(yīng)用一起打包成APK疮茄。即可通過(guò)NDK在Android中使用JNI與本地代碼(如C滥朱、C++)交互。
JNI是什么力试?
JNI是Java Native Interface的縮寫(xiě)徙邻,它提供了若干的API實(shí)現(xiàn)了Java和其他語(yǔ)言的通信(主要是C&C++)。
如何在jni中注冊(cè)native函數(shù)畸裳,有幾種注冊(cè)方式?
靜態(tài)注冊(cè)
動(dòng)態(tài)注冊(cè)
JNI調(diào)用Java方法
JNI調(diào)用Java方法:首先通過(guò)類(lèi)名找到類(lèi)缰犁,然后根據(jù)方法名找到方法的id,然后調(diào)用該方法怖糊。
進(jìn)程間通信的方式帅容?
安卓系統(tǒng)下進(jìn)程間通信主要有以下幾種方式:
1)Bundle
2)文件共享
3)AIDL
4)Messager
5)ContentProvider
6)Socket
Binder機(jī)制
Binder機(jī)制是安卓知識(shí)體系中十分重要的知識(shí)點(diǎn),需要更加全面的掌握伍伤。
http://blog.csdn.net/ccjhdopc/article/details/50829082并徘。
簡(jiǎn)述AIDL?
AIDL是一個(gè)縮寫(xiě)嚷缭,全稱(chēng)是Android Interface Definition Language饮亏,也就是Android接口定義語(yǔ)言,設(shè)計(jì)AIDL目的是為了實(shí)現(xiàn)進(jìn)程間通信阅爽,尤其是在涉及多進(jìn)程并發(fā)情況下的進(jìn)程間通信路幸。
Android進(jìn)程分類(lèi)?
1.前臺(tái)進(jìn)程(foreground process):需要用戶(hù)當(dāng)前正在進(jìn)行的操作付翁。一般滿(mǎn)足以下條件:
1)屏幕頂層運(yùn)行Activity(處于onResume()狀態(tài))简肴,用戶(hù)正與之交互
2)有BroadcastReceiver正在執(zhí)行代碼
3)有Service在其回調(diào)方法(onCreate()、onStart()百侧、onDestroy())中正在執(zhí)行代碼
這種進(jìn)程較少砰识,一般來(lái)作為最后的手段來(lái)回收內(nèi)存
2.可視進(jìn)程(visible process):做用戶(hù)當(dāng)前意識(shí)到的工作。一般滿(mǎn)足以下條件:
1)屏幕上顯示Activity佣渴,但不可操作(處于onPause()狀態(tài)) 辫狼。
2)有service通過(guò)調(diào)用Service.startForeground(),作為一個(gè)前臺(tái)服務(wù)運(yùn)行 辛润。
3)含有用戶(hù)意識(shí)到的特定的服務(wù)膨处,如動(dòng)態(tài)壁紙、輸入法等 砂竖。
這些進(jìn)程很重要真椿,一般不會(huì)殺死,除非這樣做可以使得所有前臺(tái)進(jìn)程存活乎澄。
3.服務(wù)進(jìn)程(service process):含有以startService()方法啟動(dòng)的service突硝。雖然該進(jìn)程用戶(hù)不直接可見(jiàn),但是它們一般做一些用戶(hù)關(guān)注的事情(如數(shù)據(jù)的上傳與下載)置济。
這些進(jìn)程一般不會(huì)殺死解恰,除非系統(tǒng)內(nèi)存不足以保持前臺(tái)進(jìn)程和可視進(jìn)程的運(yùn)行锋八。對(duì)于長(zhǎng)時(shí)間運(yùn)行的service(如30分鐘以上),系統(tǒng)會(huì)考慮將之降級(jí)為緩存進(jìn)程护盈,避免長(zhǎng)時(shí)間運(yùn)行導(dǎo)致內(nèi)存泄漏或其他問(wèn)題查库,占用過(guò)多RAM以至于系統(tǒng)無(wú)法分配充足資源給緩存進(jìn)程。
4.緩存/后臺(tái)進(jìn)程(cached/background process):一般來(lái)說(shuō)包含以下條件:
1)包含多個(gè)Activity實(shí)例黄琼,但是都不可見(jiàn)(處于onStop()且已返回)樊销。 系統(tǒng)如有內(nèi)存需要,可隨意殺死脏款。