金三銀四,Android高級開發(fā)面試題目唬渗,幫你助力

最近金三銀四典阵,相信不少朋友都在躍躍欲動,看看市場機會谣妻,連夜整理了一波Android高級開發(fā)面試題目萄喳,幫你助力卒稳!

Java基礎(chǔ)
1蹋半、內(nèi)部類的作用

內(nèi)部類可以用多個實例,每個實例都有自己的狀態(tài)信息充坑,并且與其他外圍對象的信息相互獨立减江。

在單個外部類中,可以讓多個內(nèi)部類以不同的方式實現(xiàn)同一個接口捻爷,或者繼承同一個類辈灼。

創(chuàng)建內(nèi)部類對象的時刻并不依賴于外圍類對象的創(chuàng)建。

內(nèi)部類并沒有令人迷惑的“is-a”關(guān)系也榄,他就是一個獨立的實體巡莹。

內(nèi)部類提供了更好的封裝,除了該外圍類甜紫,其他類都不能訪問

2降宅、父類的靜態(tài)方法能否被子類重寫,為什么囚霸?

不能

子類繼承父類后腰根,用相同的靜態(tài)方法和非靜態(tài)方法,這時非靜態(tài)方法覆蓋父類中的方法(即方法重寫)拓型,父類的該靜態(tài)方法被隱藏(如果對象是父類則調(diào)用該隱藏的方法)额嘿,另外子類可繼承父類的靜態(tài)與非靜態(tài)方法,至于方法重載我覺得它其中一要素就是在同一類中劣挫,不能說父類中的什么方法與子類里的什么方法是方法重載的體現(xiàn)

3册养、哪些情況下的對象會被垃圾回收機制處理掉

Java垃圾回收機制最基本的做法是分代回收。內(nèi)存中的區(qū)域被劃分成不同的世代压固,對象根據(jù)其存活的時間被保存在對應(yīng)世代的區(qū)域中球拦。一般的實現(xiàn)是劃分成3個世代:年輕、年老和永久。內(nèi)存的分配是發(fā)生在年輕世代中的刘莹。當(dāng)一個對象存活時間足夠長的時候阎毅,它就會被復(fù)制到年老世代中。對于不同的世代可以使用不同的垃圾回收算法点弯。進行世代劃分的出發(fā)點是對應(yīng)用中對象存活時間進行研究之后得出的統(tǒng)計規(guī)律扇调。一般來說,一個應(yīng)用中的大部分對象的存活時間都很短抢肛。比如局部變量的存活時間就只在方法的執(zhí)行過程中狼钮。基于這一點捡絮,對于年輕世代的垃圾回收算法就可以很有針對性熬芜。

4、進程和線程的區(qū)別

簡而言之,一個程序至少有一個進程,一個進程至少有一個線程福稳。

線程的劃分尺度小于進程涎拉,使得多線程程序的并發(fā)性高。

另外的圆,進程在執(zhí)行過程中擁有獨立的內(nèi)存單元鼓拧,而多個線程共享內(nèi)存,從而極大地提高了程序的運行效率越妈。

線程在執(zhí)行過程中與進程還是有區(qū)別的季俩。每個獨立的線程有一個程序運行的入口、順序執(zhí)行序列和程序的出口梅掠。但是線程不能夠獨立執(zhí)行酌住,必須依存在應(yīng)用程序中,由應(yīng)用程序提供多個線程執(zhí)行控制阎抒。

從邏輯角度來看酪我,多線程的意義在于一個應(yīng)用程序中,有多個執(zhí)行部分可以同時執(zhí)行挠蛉。但操作系統(tǒng)并沒有將多個線程看做多個獨立的應(yīng)用祭示,來實現(xiàn)進程的調(diào)度和管理以及資源分配。這就是進程和線程的重要區(qū)別谴古。

進程是具有一定獨立功能的程序關(guān)于某個數(shù)據(jù)集合上的一次運行活動,進程是系統(tǒng)進行資源分配和調(diào)度的一個獨立單位.

線程是進程的一個實體,是CPU調(diào)度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程自己基本上不擁有系統(tǒng)資源,只擁有一點在運行中必不可少的資源(如程序計數(shù)器,一組寄存器和棧),但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源.

一個線程可以創(chuàng)建和撤銷另一個線程;同一個進程中的多個線程之間可以并發(fā)執(zhí)行.

進程和線程的主要差別在于它們是不同的操作系統(tǒng)資源管理方式质涛。進程有獨立的地址空間,一個進程崩潰后掰担,在保護模式下不會對其它進程產(chǎn)生影響汇陆,而線程只是一個進程中的不同執(zhí)行路徑。線程有自己的堆棧和局部變量带饱,但線程之間沒有單獨的地址空間毡代,一個線程死掉就等于整個進程死掉阅羹,所以多進程的程序要比多線程的程序健壯,但在進程切換時教寂,耗費資源較大捏鱼,效率要差一些。但對于一些要求同時進行并且又要共享某些變量的并發(fā)操作酪耕,只能用線程导梆,不能用進程。如果有興趣深入的話迂烁,我建議你們看看《現(xiàn)代操作系統(tǒng)》或者《操作系統(tǒng)的設(shè)計與實現(xiàn)》看尼。對就個問題說得比較清楚。

5盟步、HashMap的實現(xiàn)原理

HashMap概述:HashMap是基于哈希表的Map接口的非同步實現(xiàn)藏斩。此實現(xiàn)提供所有可選的映射操作,并允許使用null值和null鍵却盘。此類不保證映射的順序狰域,特別是它不保證該順序恒久不變。

HashMap的數(shù)據(jù)結(jié)構(gòu):在java編程語言中谷炸,最基本的結(jié)構(gòu)就是兩種北专,一個是數(shù)組,另外一個是模擬指針(引用)旬陡,所有的數(shù)據(jù)結(jié)構(gòu)都可以用這兩個基本結(jié)構(gòu)來構(gòu)造的,HashMap也不例外语婴。HashMap實際上是一個“鏈表散列”的數(shù)據(jù)結(jié)構(gòu)描孟,即數(shù)組和鏈表的結(jié)合體。

HashMap底層就是一個數(shù)組結(jié)構(gòu)砰左,數(shù)組中的每一項又是一個鏈表匿醒。當(dāng)新建一個HashMap的時候,就會初始化一個數(shù)組缠导。

6廉羔、String、StringBuffer僻造、StringBuilder區(qū)別

String 字符串常量

StringBuffer 字符串變量(線程安全)

StringBuilder 字符串變量(非線程安全)

簡要的說憋他, String 類型和 StringBuffer 類型的主要性能區(qū)別其實在于 String 是不可變的對象, 因此在每次對 String 類型進行改變的時候其實都等同于生成了一個新的 String 對象,然后將指針指向新的 String 對象髓削,所以經(jīng)常改變內(nèi)容的字符串最好不要用String 竹挡,因為每次生成對象都會對系統(tǒng)性能產(chǎn)生影響,特別當(dāng)內(nèi)存中無引用對象多了以后,JVM 的 GC 就會開始工作立膛,那速度是一定會相當(dāng)慢的揪罕。

而如果是使用 StringBuffer 類則結(jié)果就不一樣了梯码,每次結(jié)果都會對 StringBuffer 對象本身進行操作嚷兔,而不是生成新的對象模庐,再改變對象引用属铁。所以在一般情況下我們推薦使用 StringBuffer 行剂,特別是字符串對象經(jīng)常改變的情況下埠况。而在某些特別情況下敦迄, String 對象的字符串拼接其實是被 JVM 解釋成了 StringBuffer 對象的拼接鲜滩,所以這些時候 String 對象的速度并不會比 StringBuffer 對象慢搭独,而特別是以下的字符串對象生成中搅窿, String 效率是遠要比 StringBuffer 快的:

在大部分情況下 StringBuffer > String

Java.lang.StringBuffer線程安全的可變字符序列嘁酿。一個類似于 String 的字符串緩沖區(qū),但不能修改男应。雖然在任意時間點上它都包含某種特定的字符序列闹司,但通過某些方法調(diào)用可以改變該序列的長度和內(nèi)容。

可將字符串緩沖區(qū)安全地用于多個線程沐飘∮巫可以在必要時對這些方法進行同步,因此任意特定實例上的所有操作就好像是以串行順序發(fā)生的耐朴,該順序與所涉及的每個線程進行的方法調(diào)用順序一致借卧。

StringBuffer 上的主要操作是 append 和 insert 方法,可重載這些方法筛峭,以接受任意類型的數(shù)據(jù)铐刘。每個方法都能有效地將給定的數(shù)據(jù)轉(zhuǎn)換成字符串,然后將該字符串的字符追加或插入到字符串緩沖區(qū)中影晓。append 方法始終將這些字符添加到緩沖區(qū)的末端镰吵;而 insert 方法則在指定的點添加字符。

在大部分情況下 StringBuilder > StringBuffer

java.lang.StringBuilder一個可變的字符序列是5.0新增的挂签。此類提供一個與 StringBuffer 兼容的 API疤祭,但不保證同步。該類被設(shè)計用作 StringBuffer 的一個簡易替換饵婆,用在字符串緩沖區(qū)被單個線程使用的時候(這種情況很普遍)勺馆。如果可能,建議優(yōu)先采用該類侨核,因為在大多數(shù)實現(xiàn)中草穆,它比 StringBuffer 要快。兩者的方法基本相同

7芹关、什么導(dǎo)致線程阻塞

線程的阻塞

為了解決對共享存儲區(qū)的訪問沖突续挟,Java 引入了同步機制,現(xiàn)在讓我們來考察多個線程對共享資源的訪問侥衬,顯然同步機制已經(jīng)不夠了诗祸,因為在任意時刻所要求的資源不一定已經(jīng)準(zhǔn)備好了被訪問跑芳,反過來,同一時刻準(zhǔn)備好了的資源也可能不止一個直颅。為了解決這種情況下的訪問控制問題博个,Java 引入了對阻塞機制的支持.

阻塞指的是暫停一個線程的執(zhí)行以等待某個條件發(fā)生(如某資源就緒),學(xué)過操作系統(tǒng)的同學(xué)對它一定已經(jīng)很熟悉了功偿。Java 提供了大量方法來支持阻塞盆佣,下面讓我們逐一分析。

sleep() 方法:sleep() 允許 指定以毫秒為單位的一段時間作為參數(shù)械荷,它使得線程在指定的時間內(nèi)進入阻塞狀態(tài)共耍,不能得到CPU 時間,指定的時間一過吨瞎,線程重新進入可執(zhí)行狀態(tài)痹兜。 典型地,sleep() 被用在等待某個資源就緒的情形:測試發(fā)現(xiàn)條件不滿足后颤诀,讓線程阻塞一段時間后重新測試字旭,直到條件滿足為止。

suspend() 和 resume() 方法:兩個方法配套使用崖叫,suspend()使得線程進入阻塞狀態(tài)遗淳,并且不會自動恢復(fù),必須其對應(yīng)的resume() 被調(diào)用心傀,才能使得線程重新進入可執(zhí)行狀態(tài)屈暗。典型地,suspend() 和 resume() 被用在等待另一個線程產(chǎn)生的結(jié)果的情形:測試發(fā)現(xiàn)結(jié)果還沒有產(chǎn)生后剧包,讓線程阻塞恐锦,另一個線程產(chǎn)生了結(jié)果后,調(diào)用 resume() 使其恢復(fù)疆液。

yield() 方法:yield() 使得線程放棄當(dāng)前分得的 CPU 時間,但是不使線程阻塞陕贮,即線程仍處于可執(zhí)行狀態(tài)堕油,隨時可能再次分得 CPU 時間。調(diào)用 yield() 的效果等價于調(diào)度程序認為該線程已執(zhí)行了足夠的時間從而轉(zhuǎn)到另一個線程.

wait() 和 notify() 方法:兩個方法配套使用肮之,wait() 使得線程進入阻塞狀態(tài)掉缺,它有兩種形式,一種允許 指定以毫秒為單位的一段時間作為參數(shù)戈擒,另一種沒有參數(shù)眶明,前者當(dāng)對應(yīng)的 notify() 被調(diào)用或者超出指定時間時線程重新進入可執(zhí)行狀態(tài),后者則必須對應(yīng)的 notify() 被調(diào)用.

初看起來它們與 suspend() 和 resume() 方法對沒有什么分別筐高,但是事實上它們是截然不同的搜囱。區(qū)別的核心在于丑瞧,前面敘述的所有方法,阻塞時都不會釋放占用的鎖(如果占用了的話)蜀肘,而這一對方法則相反绊汹。

首先,前面敘述的所有方法都隸屬于 Thread 類扮宠,但是這一對卻直接隸屬于 Object 類西乖,也就是說,所有對象都擁有這一對方法坛增。初看起來這十分不可思議获雕,但是實際上卻是很自然的,因為這一對方法阻塞時要釋放占用的鎖收捣,而鎖是任何對象都具有的届案,調(diào)用任意對象的 wait() 方法導(dǎo)致線程阻塞,并且該對象上的鎖被釋放坏晦。而調(diào)用 任意對象的notify()方法則導(dǎo)致因調(diào)用該對象的 wait() 方法而阻塞的線程中隨機選擇的一個解除阻塞(但要等到獲得鎖后才真正可執(zhí)行)萝玷。

其次,前面敘述的所有方法都可在任何位置調(diào)用昆婿,但是這一對方法卻必須在 synchronized 方法或塊中調(diào)用球碉,理由也很簡單,只有在synchronized 方法或塊中當(dāng)前線程才占有鎖仓蛆,才有鎖可以釋放睁冬。同樣的道理,調(diào)用這一對方法的對象上的鎖必須為當(dāng)前線程所擁有看疙,這樣才有鎖可以釋放豆拨。因此,這一對方法調(diào)用必須放置在這樣的 synchronized 方法或塊中能庆,該方法或塊的上鎖對象就是調(diào)用這一對方法的對象施禾。若不滿足這一條件,則程序雖然仍能編譯搁胆,但在運行時會出現(xiàn)IllegalMonitorStateException 異常弥搞。

wait() 和 notify() 方法的上述特性決定了它們經(jīng)常和synchronized方法或塊一起使用,將它們和操作系統(tǒng)的進程間通信機制作一個比較就會發(fā)現(xiàn)它們的相似性:synchronized方法或塊提供了類似于操作系統(tǒng)原語的功能渠旁,它們的執(zhí)行不會受到多線程機制的干擾攀例,而這一對方法則相當(dāng)于 block 和wakeup 原語(這一對方法均聲明為 synchronized)。它們的結(jié)合使得我們可以實現(xiàn)操作系統(tǒng)上一系列精妙的進程間通信的算法(如信號量算法)顾腊,并用于解決各種復(fù)雜的線程間通信問題粤铭。

關(guān)于 wait() 和 notify() 方法最后再說明兩點:

a、調(diào)用 notify() 方法導(dǎo)致解除阻塞的線程是從因調(diào)用該對象的 wait() 方法而阻塞的線程中隨機選取的杂靶,我們無法預(yù)料哪一個線程將會被選擇梆惯,所以編程時要特別小心酱鸭,避免因這種不確定性而產(chǎn)生問題。

b加袋、除了 notify()凛辣,還有一個方法 notifyAll() 也可起到類似作用,唯一的區(qū)別在于职烧,調(diào)用 notifyAll() 方法將把因調(diào)用該對象的 wait() 方法而阻塞的所有線程一次性全部解除阻塞扁誓。當(dāng)然,只有獲得鎖的那一個線程才能進入可執(zhí)行狀態(tài)蚀之。

Android基礎(chǔ)
1蝗敢、是否使用過IntentService,作用是什么足删,AIDL解決了什么問題寿谴?

生成一個默認的且與主線程互相獨立的工作者線程來執(zhí)行所有傳送至onStartCommand() 方法的Intetnt。

生成一個工作隊列來傳送Intent對象給你的onHandleIntent()方法失受,同一時刻只傳送一個Intent對象讶泰,這樣一來,你就不必擔(dān)心多線程的問題拂到。在所有的請求(Intent)都被執(zhí)行完以后會自動停止服務(wù)痪署,所以,你不需要自己去調(diào)用stopSelf()方法來停止兄旬。

該服務(wù)提供了一個onBind()方法的默認實現(xiàn)狼犯,它返回null

提供了一個onStartCommand()方法的默認實現(xiàn),它將Intent先傳送至工作隊列领铐,然后從工作隊列中每次取出一個傳送至onHandleIntent()方法悯森,在該方法中對Intent對相應(yīng)的處理。

AIDL (Android Interface Definition Language) 是一種IDL 語言绪撵,用于生成可以在Android設(shè)備上兩個進程之間進行進程間通信(interprocess communication, IPC)的代碼瓢姻。如果在一個進程中(例如Activity)要調(diào)用另一個進程中(例如Service)對象的操作,就可以使用AIDL生成可序列化的參數(shù)音诈。 AIDL IPC機制是面向接口的汹来,像COM或Corba一樣,但是更加輕量級改艇。它是使用代理類在客戶端和實現(xiàn)端傳遞數(shù)據(jù)。

2坟岔、Activity谒兄、Window、View三者的差別社付?

Activity像一個工匠(控制單元)承疲,Window像窗戶(承載模型)邻耕,View像窗花(顯示視圖) LayoutInflater像剪刀,Xml配置像窗花圖紙燕鸽。

在Activity中調(diào)用attach兄世,創(chuàng)建了一個Window

創(chuàng)建的window是其子類PhoneWindow,在attach中創(chuàng)建PhoneWindow

在Activity中調(diào)用setContentView(R.layout.xxx)

其中實際上是調(diào)用的getWindow().setContentView()

調(diào)用PhoneWindow中的setContentView方法

創(chuàng)建ParentView:作為ViewGroup的子類啊研,實際是創(chuàng)建的DecorView(作為FramLayout的子類)

將指定的R.layout.xxx進行填充通過布局填充器進行填充【其中的parent指的就是DecorView】

調(diào)用到ViewGroup

調(diào)用ViewGroup的removeAllView()御滩,先將所有的view移除掉
添加新的view:addView()

3、Fragment 特點

Fragment可以作為Activity界面的一部分組成出現(xiàn)党远;

可以在一個Activity中同時出現(xiàn)多個Fragment削解,并且一個Fragment也可以在多個Activity中使用;

在Activity運行過程中沟娱,可以添加氛驮、移除或者替換Fragment;

Fragment可以響應(yīng)自己的輸入事件济似,并且有自己的生命周期矫废,它們的生命周期會受宿主Activity的生命周期影響。

4砰蠢、Handler蓖扑、Thread和HandlerThread的差別?

http://blog.csdn.net/guolin_blog/article/details/9991569

http://droidyue.com/blog/2015/11/08/make-use-of-handlerthread/

從Android中Thread(java.lang.Thread -> java.lang.Object)描述可以看出娩脾,Android的Thread沒有對Java的Thread做任何封裝赵誓,但是Android提供了一個繼承自Thread的類HandlerThread(android.os.HandlerThread -> java.lang.Thread),這個類對Java的Thread做了很多便利Android系統(tǒng)的封裝柿赊。

android.os.Handler可以通過Looper對象實例化俩功,并運行于另外的線程中,Android提供了讓Handler運行于其它線程的線程實現(xiàn)碰声,也就是HandlerThread诡蜓。HandlerThread對象start后可以獲得其Looper對象,并且使用這個Looper對象實例Handler胰挑。

5蔓罚、Launch mode應(yīng)用場景

Standard,創(chuàng)建一個新的Activity瞻颂。

SingleTop豺谈,棧頂不是該類型的Activity,創(chuàng)建一個新的Activity贡这。否則茬末,onNewIntent。

SingleTask,回退棧中沒有該類型的Activity丽惭,創(chuàng)建Activity击奶,否則,onNewIntent+ClearTop责掏。

注意:

設(shè)置了"singleTask"啟動模式的Activity柜砾,它在啟動的時候,會先在系統(tǒng)中查找屬性值affinity等于它的屬性值taskAffinity的Task存在换衬; 如果存在這樣的Task痰驱,它就會在這個Task中啟動,否則就會在新的任務(wù)棧中啟動冗疮。因此萄唇, 如果我們想要設(shè)置了"singleTask"啟動模式的Activity在新的任務(wù)中啟動,就要為它設(shè)置一個獨立的taskAffinity屬性值术幔。

如果設(shè)置了"singleTask"啟動模式的Activity不是在新的任務(wù)中啟動時另萤,它會在已有的任務(wù)中查看是否已經(jīng)存在相應(yīng)的Activity實例, 如果存在诅挑,就會把位于這個Activity實例上面的Activity全部結(jié)束掉四敞,即最終這個Activity 實例會位于任務(wù)的Stack頂端中。

在一個任務(wù)棧中只有一個”singleTask”啟動模式的Activity存在拔妥。他的上面可以有其他的Activity忿危。這點與singleInstance是有區(qū)別的。
singleInstance没龙,回退棧中铺厨,只有這一個Activity,沒有其他Activity硬纤。

SingleTop適合接收通知啟動的內(nèi)容顯示頁面解滓。

例如,某個新聞客戶端的新聞內(nèi)容頁面筝家,如果收到10個新聞推送洼裤,每次都打開一個新聞內(nèi)容頁面是很煩人的。

singleTask適合作為程序入口點溪王。

例如瀏覽器的主界面腮鞍。不管從多少個應(yīng)用啟動瀏覽器,只會啟動主界面一次莹菱,其余情況都會走onNewIntent移国,并且會清空主界面上面的其他頁面。

singleInstance應(yīng)用場景:

鬧鈴的響鈴界面道伟。 你以前設(shè)置了一個鬧鈴:上午6點桥狡。在上午5點58分,你啟動了鬧鈴設(shè)置界面,并按 Home 鍵回桌面裹芝;在上午5點59分時,你在微信和朋友聊天娜汁;在6點時嫂易,鬧鈴響了,并且彈出了一個對話框形式的 Activity(名為 AlarmAlertActivity) 提示你到6點了(這個 Activity 就是以 SingleInstance 加載模式打開的)掐禁,你按返回鍵怜械,回到的是微信的聊天界面,這是因為 AlarmAlertActivity 所在的 Task 的棧只有他一個元素傅事, 因此退出之后這個 Task 的椔圃剩空了。如果是以 SingleTask 打開 AlarmAlertActivity蹭越,那么當(dāng)鬧鈴響了的時候障本,按返回鍵應(yīng)該進入鬧鈴設(shè)置界面。

6响鹃、Android事件分發(fā)機制

http://www.reibang.com/p/38015afcdb58

7驾霜、view繪制流程

http://www.reibang.com/p/bb7977990baa

8、post和postDelay

9买置、線程同步

http://www.itzhai.com/java-based-notebook-thread-synchronization-problem-solving-synchronization-problems-synchronized-block-synchronized-methods.html#read-more

http://www.juwends.com/tech/android/android-inter-thread-comm.html

10粪糙、單例模式

public class Singleton{
private volatile static Singleton mSingleton;
private Singleton(){
}
public static Singleton getInstance(){
if(mSingleton == null){
synchronized(Singleton.class){
if(mSingleton == null)
mSingleton = new Singleton();
}
}
return mSingleton;
}
}

11、什么情況導(dǎo)致內(nèi)存泄漏

a忿项、資源對象沒關(guān)閉造成的內(nèi)存泄漏

描述: 資源性對象比如(Cursor蓉冈,F(xiàn)ile文件等)往往都用了一些緩沖,我們在不使用的時候轩触,應(yīng)該及時關(guān)閉它們寞酿,以便它們的緩沖及時回收內(nèi)存。它們的緩沖不僅存在于 java虛擬機內(nèi)怕膛,還存在于java虛擬機外熟嫩。如果我們僅僅是把它的引用設(shè)置為null,而不關(guān)閉它們,往往會造成內(nèi)存泄漏褐捻。因為有些資源性對象掸茅,比如 SQLiteCursor(在析構(gòu)函數(shù)finalize(),如果我們沒有關(guān)閉它,它自己會調(diào)close()關(guān)閉)柠逞,如果我們沒有關(guān)閉它昧狮,系統(tǒng)在回收它時也會關(guān)閉它,但是這樣的效率太低了板壮。因此對于資源性對象在不使用的時候逗鸣,應(yīng)該調(diào)用它的close()函數(shù),將其關(guān)閉掉,然后才置為null.在我們的程序退出時一定要確保我們的資源性對象已經(jīng)關(guān)閉撒璧。 程序中經(jīng)常會進行查詢數(shù)據(jù)庫的操作透葛,但是經(jīng)常會有使用完畢Cursor后沒有關(guān)閉的情況。如果我們的查詢結(jié)果集比較小卿樱,對內(nèi)存的消耗不容易被發(fā)現(xiàn)僚害,只有在常時間大量操作的情況下才會復(fù)現(xiàn)內(nèi)存問題,這樣就會給以后的測試和問題排查帶來困難和風(fēng)險繁调。

b萨蚕、構(gòu)造Adapter時,沒有使用緩存的convertView

以構(gòu)造ListView的BaseAdapter為例蹄胰,在BaseAdapter中提供了方法: public View getView(int position, ViewconvertView, ViewGroup parent) 來向ListView提供每一個item所需要的view對象岳遥。初始時ListView會從BaseAdapter中根據(jù)當(dāng)前的屏幕布局實例化一定數(shù)量的 view對象,同時ListView會將這些view對象緩存起來裕寨。當(dāng)向上滾動ListView時浩蓉,原先位于最上面的list item的view對象會被回收,然后被用來構(gòu)造新出現(xiàn)的最下面的list item帮坚。這個構(gòu)造過程就是由getView()方法完成的妻往,getView()的第二個形參View convertView就是被緩存起來的list item的view對象(初始化時緩存中沒有view對象則convertView是null)。由此可以看出试和,如果我們不去使用 convertView讯泣,而是每次都在getView()中重新實例化一個View對象的話,即浪費資源也浪費時間阅悍,也會使得內(nèi)存占用越來越大好渠。 ListView回收list item的view對象的過程可以查看: android.widget.AbsListView.java --> voidaddScrapView(View scrap) 方法。 示例代碼:

public View getView(int position, ViewconvertView, ViewGroup parent) {
View view = new Xxx(...);
... ...
return view;
}

修正示例代碼:

public View getView(int position, ViewconvertView, ViewGroup parent) {
View view = null;
if (convertView != null) {
view = convertView;
populate(view, getItem(position));
...
} else {
view = new Xxx(...);
...
}
return view;
}

c节视、Bitmap對象不在使用時調(diào)用recycle()釋放內(nèi)存

有時我們會手工的操作Bitmap對象拳锚,如果一個Bitmap對象比較占內(nèi)存,當(dāng)它不在被使用的時候寻行,可以調(diào)用Bitmap.recycle()方法回收此對象的像素所占用的內(nèi)存霍掺,但這不是必須的,視情況而定拌蜘。

d膝藕、試著使用關(guān)于application的context來替代和activity相關(guān)的context

這是一個很隱晦的內(nèi)存泄漏的情況荠商。有一種簡單的方法來避免context相關(guān)的內(nèi)存泄漏膳算。最顯著地一個是避免context逃出他自己的范圍之外族跛。使用Application context。這個context的生存周期和你的應(yīng)用的生存周期一樣長举娩,而不是取決于activity的生存周期析校。如果你想保持一個長期生存的對象构罗,并且這個對象需要一個context,記得使用application對象。你可以通過調(diào)用 Context.getApplicationContext() or Activity.getApplication()來獲得智玻。更多的請看這篇文章如何避免 Android內(nèi)存泄漏遂唧。

e、注冊沒反注冊造成的內(nèi)存泄漏

一些Android程序可能引用我們的Anroid程序的對象(比如注冊機制)尚困。即使我們的Android程序已經(jīng)結(jié)束了蠢箩,但是別的引用程序仍然還有對我們的Android程序的某個對象的引用,泄漏的內(nèi)存依然不能被垃圾回收事甜。調(diào)用registerReceiver后未調(diào)用unregisterReceiver。 比如:假設(shè)我們希望在鎖屏界面(LockScreen)中滔韵,監(jiān)聽系統(tǒng)中的電話服務(wù)以獲取一些信息(如信號強度等)逻谦,則可以在LockScreen中定義一個 PhoneStateListener的對象,同時將它注冊到TelephonyManager服務(wù)中陪蜻。對于LockScreen對象邦马,當(dāng)需要顯示鎖屏界面的時候就會創(chuàng)建一個LockScreen對象,而當(dāng)鎖屏界面消失的時候LockScreen對象就會被釋放掉宴卖。 但是如果在釋放 LockScreen對象的時候忘記取消我們之前注冊的PhoneStateListener對象滋将,則會導(dǎo)致LockScreen無法被垃圾回收。如果不斷的使鎖屏界面顯示和消失症昏,則最終會由于大量的LockScreen對象沒有辦法被回收而引起OutOfMemory,使得system_process 進程掛掉随闽。 雖然有些系統(tǒng)程序,它本身好像是可以自動取消注冊的(當(dāng)然不及時)肝谭,但是我們還是應(yīng)該在我們的程序中明確的取消注冊掘宪,程序結(jié)束時應(yīng)該把所有的注冊都取消掉。

f攘烛、集合中對象沒清理造成的內(nèi)存泄漏

我們通常把一些對象的引用加入到了集合中魏滚,當(dāng)我們不需要該對象時,并沒有把它的引用從集合中清理掉坟漱,這樣這個集合就會越來越大鼠次。如果這個集合是static的話,那情況就更嚴重了芋齿。

12腥寇、ANR定位和如何避免?

如果開發(fā)機器上出現(xiàn)問題沟突,我們可以通過查看/data/anr/traces.txt即可花颗,最新的ANR信息在最開始部分。

主線程被IO操作(從4.0之后網(wǎng)絡(luò)IO不允許在主線程中)阻塞惠拭。

主線程中存在耗時的計算

主線程中錯誤的操作扩劝,比如Thread.wait或者Thread.sleep等 Android系統(tǒng)會監(jiān)控程序的響應(yīng)狀況庸论,一旦出現(xiàn)下面兩種情況,則彈出ANR對話框

應(yīng)用在5秒內(nèi)未響應(yīng)用戶的輸入事件(如按鍵或者觸摸)

BroadcastReceiver未在10秒內(nèi)完成相關(guān)的處理

Service在特定的時間內(nèi)無法處理完成 20秒

避免

使用AsyncTask處理耗時IO操作棒呛。

使用Thread或者HandlerThread時聂示,調(diào)用Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND)設(shè)置優(yōu)先級,否則仍然會降低程序響應(yīng)簇秒,因為默認Thread的優(yōu)先級和主線程相同鱼喉。

使用Handler處理工作線程結(jié)果,而不是使用Thread.wait()或者Thread.sleep()來阻塞主線程趋观。

Activity的onCreate和onResume回調(diào)中盡量避免耗時的代碼

BroadcastReceiver中onReceive代碼也要盡量減少耗時扛禽,建議使用IntentService處理。

13皱坛、什么情況導(dǎo)致OOM以及如何避免?

http://blog.csdn.net/yangxuehui1990/article/details/44994763

http://blog.csdn.net/ljx19900116/article/details/50037627

14编曼、Android Service與Activity之間通信的幾種方式?

通過Binder對象

通過Broadcast(廣播)的形式

15剩辟、如何保證service在后臺盡量不被kill

onStartCommand方法掐场,返回START_STICKY

START_STICKY 在運行onStartCommand后service進程被kill后,那將保留在開始狀態(tài)贩猎,但是不保留那些傳入的intent熊户。不久后service就會再次嘗試重新創(chuàng)建,因為保留在開始狀態(tài)吭服,在創(chuàng)建 service后將保證調(diào)用onstartCommand嚷堡。如果沒有傳遞任何開始命令給service,那將獲取到null的intent噪馏。

START_NOT_STICKY 在運行onStartCommand后service進程被kill后麦到,并且沒有新的intent傳遞給它。Service將移出開始狀態(tài)欠肾,并且直到新的明顯的方法(startService)調(diào)用才重新創(chuàng)建瓶颠。因為如果沒有傳遞任何未決定的intent那么service是不會啟動,也就是期間onstartCommand不會接收到任何null的intent刺桃。

START_REDELIVER_INTENT 在運行onStartCommand后service進程被kill后粹淋,系統(tǒng)將會再次啟動service,并傳入最后一個intent給onstartCommand瑟慈。直到調(diào)用stopSelf(int)才停止傳遞intent桃移。如果在被kill后還有未處理好的intent,那被kill后服務(wù)還是會自動啟動葛碧。因此onstartCommand不會接收到任何null的intent借杰。

提升service優(yōu)先級

在AndroidManifest.xml文件中對于intent-filter可以通過android:priority="1000"這個屬性設(shè)置最高優(yōu)先級,1000是最高值进泼,如果數(shù)字越小則優(yōu)先級越低蔗衡,同時適用于廣播纤虽。

提升service進程優(yōu)先級

Android中的進程是托管的,當(dāng)系統(tǒng)進程空間緊張的時候绞惦,會依照優(yōu)先級自動進行進程的回收逼纸。Android將進程分為6個等級,它們按優(yōu)先級順序由高到低依次是:

前臺進程( FOREGROUND_APP)

可視進程(VISIBLE_APP )

次要服務(wù)進程(SECONDARY_SERVER )

后臺進程 (HIDDEN_APP)

內(nèi)容供應(yīng)節(jié)點(CONTENT_PROVIDER)

空進程(EMPTY_APP)

當(dāng)service運行在低內(nèi)存的環(huán)境時,將會kill掉一些存在的進程济蝉。因此進程的優(yōu)先級將會很重要杰刽,可以使用startForeground 將service放到前臺狀態(tài)。這樣在低內(nèi)存時被kill的幾率會低一些王滤。

onDestroy方法里重啟service

service+broadcast方式贺嫂,就是當(dāng)service走ondestory的時候,發(fā)送一個自定義的廣播雁乡,當(dāng)收到廣播的時候涝婉,重新啟動service;

Application加上Persistent屬性

監(jiān)聽系統(tǒng)廣播判斷Service狀態(tài)

16蔗怠、RequestLayout,onLayout吩跋,onDraw寞射,DrawChild區(qū)別與聯(lián)系

requestLayout()方法 :會導(dǎo)致調(diào)用measure()過程 和 layout()過程 。說明:只是對View樹重新布局layout過程包括measure()和layout()過程锌钮,不會調(diào)用draw()過程桥温,但不會重新繪制 任何視圖包括該調(diào)用者本身。

onLayout()方法(如果該View是ViewGroup對象梁丘,需要實現(xiàn)該方法侵浸,對每個子視圖進行布局)

調(diào)用onDraw()方法繪制視圖本身(每個View都需要重載該方法,ViewGroup不需要實現(xiàn)該方法)

drawChild()去重新回調(diào)每個子視圖的draw()方法

17氛谜、invalidate()和postInvalidate() 的區(qū)別及使用

http://blog.csdn.net/mars2639/article/details/6650876

18掏觉、LinearLayout對比RelativeLayout

RelativeLayout會讓子View調(diào)用2次onMeasure,LinearLayout 在有weight時值漫,也會調(diào)用子View2次onMeasure

RelativeLayout的子View如果高度和RelativeLayout不同澳腹,則會引發(fā)效率問題,當(dāng)子View很復(fù)雜時杨何,這個問題會更加嚴重酱塔。如果可以,盡量使用padding代替margin危虱。

在不影響層級深度的情況下,使用LinearLayout和FrameLayout而不是RelativeLayout羊娃。

19、優(yōu)化自定義view

為了加速你的view埃跷,對于頻繁調(diào)用的方法蕊玷,需要盡量減少不必要的代碼邮利。先從onDraw開始,需要特別注意不應(yīng)該在這里做內(nèi)存分配的事情集畅,因為它會導(dǎo)致GC近弟,從而導(dǎo)致卡頓。在初始化或者動畫間隙期間做分配內(nèi)存的動作挺智。不要在動畫正在執(zhí)行的時候做內(nèi)存分配的事情祷愉。

你還需要盡可能的減少onDraw被調(diào)用的次數(shù),大多數(shù)時候?qū)е耾nDraw都是因為調(diào)用了invalidate().因此請盡量減少調(diào)用invaildate()的次數(shù)赦颇。如果可能的話二鳄,盡量調(diào)用含有4個參數(shù)的invalidate()方法而不是沒有參數(shù)的invalidate()。沒有參數(shù)的invalidate會強制重繪整個view媒怯。

另外一個非常耗時的操作是請求layout订讼。任何時候執(zhí)行requestLayout(),會使得Android UI系統(tǒng)去遍歷整個View的層級來計算出每一個view的大小扇苞。如果找到有沖突的值欺殿,它會需要重新計算好幾次。另外需要盡量保持View的層級是扁平化的鳖敷,這樣對提高效率很有幫助脖苏。

如果你有一個復(fù)雜的UI,你應(yīng)該考慮寫一個自定義的ViewGroup來執(zhí)行他的layout操作定踱。與內(nèi)置的view不同棍潘,自定義的view可以使得程序僅僅測量這一部分,這避免了遍歷整個view的層級結(jié)構(gòu)來計算大小崖媚。這個PieChart 例子展示了如何繼承ViewGroup作為自定義view的一部分亦歉。PieChart 有子views,但是它從來不測量它們畅哑。而是根據(jù)他自身的layout法則肴楷,直接設(shè)置它們的大小。

20敢课、ContentProvider

http://www.reibang.com/p/ea8bc4aaf057

21阶祭、Android 設(shè)計模式

http://blog.csdn.net/bboyfeiyu/article/details/44563871

22、MVC直秆、MVP濒募、MVM區(qū)別?

https://www.cnblogs.com/guwei4037/p/5591183.html

小編給大家準(zhǔn)備安卓高級開發(fā)資料
QQ群號:4112676


群二維碼.jpg

1.png

2.png

架構(gòu)3.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末圾结,一起剝皮案震驚了整個濱河市瑰剃,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌筝野,老刑警劉巖晌姚,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件粤剧,死亡現(xiàn)場離奇詭異,居然都是意外死亡挥唠,警方通過查閱死者的電腦和手機抵恋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宝磨,“玉大人弧关,你說我怎么就攤上這事』斤保” “怎么了世囊?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長窿祥。 經(jīng)常有香客問我株憾,道長,這世上最難降的妖魔是什么晒衩? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任嗤瞎,我火速辦了婚禮,結(jié)果婚禮上听系,老公的妹妹穿的比我還像新娘猫胁。我一直安慰自己,他們只是感情好跛锌,可當(dāng)我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著届惋,像睡著了一般髓帽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上脑豹,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天郑藏,我揣著相機與錄音,去河邊找鬼瘩欺。 笑死必盖,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的俱饿。 我是一名探鬼主播歌粥,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼拍埠!你這毒婦竟也來了失驶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤枣购,失蹤者是張志新(化名)和其女友劉穎嬉探,沒想到半個月后擦耀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡涩堤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年眷蜓,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胎围。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡吁系,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出痊远,到底是詐尸還是另有隱情垮抗,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布碧聪,位于F島的核電站冒版,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏逞姿。R本人自食惡果不足惜辞嗡,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望滞造。 院中可真熱鬧续室,春花似錦、人聲如沸谒养。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽买窟。三九已至丰泊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間始绍,已是汗流浹背瞳购。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留亏推,地道東北人学赛。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像吞杭,于是被迫代替她去往敵國和親盏浇。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 1芽狗,java 接口的意義: 規(guī)范缠捌,擴展,回調(diào) 規(guī)范:比如,有兩個及上的的類擁有相同的方法曼月,但是實現(xiàn)功能不一樣谊却,就可...
    漫唐閱讀 968評論 0 6
  • java 接口的意義-百度 規(guī)范、擴展哑芹、回調(diào) 抽象類的意義-樂視 為其子類提供一個公共的類型封裝子類中得重復(fù)內(nèi)容定...
    交流電1582閱讀 2,231評論 0 11
  • 1炎辨、Activity生命周期? onCreate() -> onStart() -> onResume() -> ...
    王培921223閱讀 2,387評論 0 11
  • 國內(nèi)一線互聯(lián)網(wǎng)公司內(nèi)部面試題庫聪姿,從一個老碼農(nóng)轉(zhuǎn)載的 以下面試題來自于百度碴萧、小米、樂視末购、美團破喻、58、獵豹盟榴、360曹质、新...
    next_discover閱讀 844評論 1 15
  • 有始有終方無悔, 不虧不欠自心安擎场。 酸甜苦辣人生味羽德, 雨雪風(fēng)霜四季天。 琴棋書畫動情弦迅办, 筆墨紙硯抒絕篇宅静。 成敗得...
    東方靈月閱讀 883評論 0 8