Android遇到的那些坑(持續(xù)更新中)

前景提要

這篇文章是我工作中遇到的一些坑,在這里做下歸總絮识。由于本人才疏學(xué)淺绿聘,發(fā)現(xiàn)問題,歡迎拍磚次舌。

系統(tǒng)API(版本熄攘,注意事項(xiàng))

Android library中的資源ID在R.java中不是final類型:

問題現(xiàn)象:在library中使用switch語(yǔ)句區(qū)分不同的資源ID時(shí),IDE會(huì)報(bào)錯(cuò)彼念;

原因分析:這個(gè)問題在Android Studio Project Site(http://tools.android.com/tips/non-constant-fields)有提及挪圾,在API14及以上的版本中浅萧,library所對(duì)應(yīng)的R.java中所有ID不再是final類型,所以不能將ID作為switch語(yǔ)句中的case分支屬性值洛史。

解決方案:如果涉及到區(qū)分多個(gè)ID的情況(比如監(jiān)聽回調(diào)事件惯殊、初始化通過xml給自定義View設(shè)置的屬性值等)應(yīng)該使用if...else if...else代替switch語(yǔ)句;

同一個(gè)程序內(nèi)的多個(gè)進(jìn)程之間使用SharedPreferences不安全:

問題現(xiàn)象:在同一個(gè)程序內(nèi)使用多進(jìn)程時(shí)也殖,在不同進(jìn)程間使用SharedPreferences操作數(shù)據(jù)會(huì)導(dǎo)致SP中的數(shù)據(jù)隨機(jī)丟失的情況(獲取到的值為空)土思;

原因分析:雖然API中提供了Context.MODEMULTIPROCESS模式打開SP文件,但在官方文檔(https://developer.android.com/reference/android/content/SharedPreferences.html)中已有說明:“currently this class does not support use across multiple processes”忆嗜,因?yàn)镾P在多進(jìn)程間操作是不安全的己儒,并行操作時(shí)會(huì)導(dǎo)致寫沖突。

解決方案:Github上有個(gè)開源項(xiàng)目Tray(https://github.com/grandcentrix/tray)捆毫,專門針對(duì)在多進(jìn)程中使用SP不安全的問題提供的解決方案闪湾。

Typeface初始化自定義字體慢:

問題現(xiàn)象:在使用自定義字體的頁(yè)面,進(jìn)入慢绩卤;

原因分析:使用Typeface初始化字體很耗時(shí)途样,至少需要100ms(不同文件耗時(shí)不一樣)以上的時(shí)間。

解決方案:如果在Activity的onCreate方法中初始化Typeface濒憋,會(huì)導(dǎo)致進(jìn)入Activity慢何暇,出現(xiàn)黑屏/白屏現(xiàn)象,所以應(yīng)該盡量在非UI線程中做自定義字體的初始化操作凛驮。

Activity在沒有完全顯示/已退出的情況下顯示PopupWindow異常:

問題現(xiàn)象:進(jìn)入Activity界面直接報(bào)錯(cuò)裆站,log異常顯示為:"Unable to add window -- token null is not valid";

原因分析:原因是在Activity的onCreate方法中直接顯示了PopupWindow導(dǎo)致黔夭,PopupWindow的顯示是依附在某一個(gè)View上面的(showAtLocation方法第一個(gè)參數(shù)為需要依附的view)宏胯,在Activity沒有完全顯示時(shí),PopupWindow無(wú)法依附在該View上本姥,如果在此時(shí)顯示PopupWindow會(huì)導(dǎo)致上面的異常肩袍,同樣在退出Activity后也不能正常顯示PopupWindow。

解決方案:在開發(fā)過程中需要考慮通過異步顯示PopupWindow婚惫,避免PoupWindow顯示報(bào)異常的問題氛赐。

Activity的onDestory方法調(diào)用時(shí)機(jī)不確定:

問題現(xiàn)象:連續(xù)進(jìn)入、退出某一個(gè)Activity辰妙,會(huì)出現(xiàn)Activity Crash掉的現(xiàn)象;

原因分析:在Activity的onCreate做的初始化操作(打開文件)甫窟,在onDestory做的銷毀操作(關(guān)閉文件)密浑;退出Activity后onDestory并沒有立即調(diào)用,再次快速進(jìn)入該Activity時(shí)粗井,該Activity是另外一個(gè)實(shí)例尔破,并且首先調(diào)用了新Activity的onCreate方法之后再才調(diào)用上個(gè)Activity實(shí)例的onDestory方法街图,導(dǎo)致文件剛被打開就關(guān)閉了,在程序使用數(shù)據(jù)時(shí)Crash掉懒构;

解決方案:準(zhǔn)確來(lái)講只要是系統(tǒng)方法餐济,調(diào)用時(shí)機(jī)都不確定。對(duì)于這種問題只能盡量不要在Activity的系統(tǒng)回調(diào)方法中做資源初始化和釋放的操作胆剧,比如涉及到IO操作的情況絮姆,在使用的時(shí)候才打開,使用完后立即關(guān)閉秩霍;

透明主題導(dǎo)致Activity生命周期回調(diào)的變化:

問題現(xiàn)象:從當(dāng)前Activity跳轉(zhuǎn)到其它Activity時(shí)篙悯,當(dāng)前Activity的onStop方法并沒有調(diào)用;

原因分析:給當(dāng)前Activity設(shè)置為透明主題導(dǎo)致铃绒,通過添加打印跟蹤發(fā)現(xiàn)鸽照,從該Activity跳轉(zhuǎn)到其它Activity時(shí),該Activity的onStop方法不會(huì)執(zhí)行颠悬;

解決方案:謹(jǐn)慎使用透明主題矮燎,如果必須要為Activity設(shè)置為透明主題,不要在onStop方法中做任何操作赔癌,因?yàn)樵摲椒ú⒉粫?huì)被調(diào)用诞外。透明主題存在很多問題,比如在設(shè)置為透明主題的界面按Home按鍵時(shí)届榄,會(huì)存在界面刷不干凈的情況浅乔。

不要通過Bundle傳遞很大塊的數(shù)據(jù):

問題現(xiàn)象:從目錄界面跳轉(zhuǎn)到內(nèi)容顯示界面,出現(xiàn)隨機(jī)崩潰的現(xiàn)象铝条,報(bào)的異常是:TransactionTooLargeException靖苇;

原因分析:跟蹤發(fā)現(xiàn)如果通過Bundle傳遞太大塊(>1M)的數(shù)據(jù)會(huì)在程序運(yùn)行時(shí)報(bào)TransactionTooLargeException異常,具體原因可以上官網(wǎng)查看班缰,大致意思是傳遞的序列化數(shù)據(jù)不能超過1M贤壁,否則會(huì)報(bào)TransactionTooLargeException異常;之所以隨機(jī)是因?yàn)槊看蝹鬟f的數(shù)據(jù)大小不一樣埠忘。

解決方案:如果你在不同組件之間傳遞的數(shù)據(jù)太大脾拆,甚至超過了1M,為了提高效率和程序的穩(wěn)定性莹妒,建議通過持久化的方式傳遞數(shù)據(jù)名船,即在傳遞方寫文件,在接收方去讀取這個(gè)文件旨怠;

不要在Application類中緩存數(shù)據(jù):

問題現(xiàn)象:程序從后臺(tái)切換到前臺(tái)渠驼,直接崩了;

原因分析:程序在后臺(tái)時(shí)鉴腻,為了給正在運(yùn)行的程序提供更多可使用的內(nèi)存迷扇,Application中的數(shù)據(jù)可能會(huì)被清理掉百揭,如果在Application中緩存了數(shù)據(jù),并且在程序重新回到前臺(tái)時(shí)沒有做好恢復(fù)工作蜓席,程序會(huì)出現(xiàn)不可預(yù)見的情況(比如數(shù)據(jù)錯(cuò)亂器一、崩潰等),具體可以參照這篇文章Don't Store Data in the Application Object厨内;

解決方案:不要在Application中緩存數(shù)據(jù)祈秕。

使用AsyncTask無(wú)法避開的坑:

問題現(xiàn)象:使用AsyncTask異步執(zhí)行的任務(wù)并沒有立即執(zhí)行;

原因分析:AsyncTask這個(gè)類的實(shí)現(xiàn)可謂一波三折隘庄,方案修改了好幾個(gè)版本踢步,初次引入這個(gè)類時(shí),所有的Task是放在一個(gè)獨(dú)立的后臺(tái)線程中執(zhí)行的丑掺,也就是如果有多個(gè)Task同時(shí)被調(diào)用也是順序執(zhí)行的获印;從1.6開始,改為通過線程池可以支持并行執(zhí)行多個(gè)Task街州;但從3.0開始兼丰,又改回只有一個(gè)獨(dú)立的后臺(tái)線程執(zhí)行所有Task,主要是為了避免多個(gè)Task并行執(zhí)行導(dǎo)致的程序錯(cuò)誤唆缴,但為了讓AsyncTask能夠支持多個(gè)Task并行執(zhí)行鳍征,從3.0起,增加了executeOnExecutor方法面徽,調(diào)用者自行實(shí)現(xiàn)線程池可以達(dá)到并行多個(gè)Task的效果艳丛。

解決方案:如果在某個(gè)地方需要同時(shí)執(zhí)行多個(gè)異步任務(wù),強(qiáng)烈建議使用線程池趟紊;

數(shù)據(jù)庫(kù)升級(jí)中的坑:

問題現(xiàn)象:在數(shù)據(jù)庫(kù)的某個(gè)表中增加/修改了某個(gè)字段后氮双,程序在運(yùn)行時(shí)崩潰掉了;或者在增加字段時(shí)修改了數(shù)據(jù)庫(kù)的版本號(hào)霎匈,但程序升級(jí)后戴差,原來(lái)的數(shù)據(jù)丟失了;

原因分析:SQlite數(shù)據(jù)庫(kù)升級(jí)時(shí)需要修改OpenHelper中的版本號(hào)铛嘱,并且數(shù)據(jù)庫(kù)升級(jí)會(huì)刪掉原來(lái)數(shù)據(jù)庫(kù)中的數(shù)據(jù)暖释,需要手動(dòng)將原數(shù)據(jù)庫(kù)中的數(shù)據(jù)拷貝到高版本的數(shù)據(jù)庫(kù)中;

解決方案:做好數(shù)據(jù)庫(kù)升級(jí)的恢復(fù)工作墨吓,避免出現(xiàn)崩潰球匕、數(shù)據(jù)丟失的情況。

程序在未啟動(dòng)的情況下帖烘,靜態(tài)注冊(cè)的廣播無(wú)法收到消息:

問題現(xiàn)象:程序添加了對(duì)開機(jī)廣播的監(jiān)聽亮曹,但無(wú)法接收到;

原因分析:這個(gè)問題只有在程序安裝但沒有啟動(dòng)時(shí)才會(huì)出現(xiàn),只要程序啟動(dòng)過一次后就不會(huì)有這個(gè)問題乾忱。并且只有在Android 3.1及以上的版本才會(huì)出現(xiàn),具體原因是:從Android3.1開始历极,新安裝的程序會(huì)被置于"stopped"狀態(tài)窄瘟,并且只有在至少手動(dòng)啟動(dòng)這個(gè)程序一次后該程序才會(huì)改變狀態(tài),能夠正常接收到指定的廣播消息趟卸。Android這樣做的目的是防止廣播無(wú)意或者不必要地開啟未啟動(dòng)的APP后臺(tái)服務(wù)蹄葱。也就是說在Android3.1及以上的版本,程序在未啟動(dòng)的情況下通過應(yīng)用自身完成一些操作是不可能的锄列,但Android提供了一種借助其它應(yīng)用發(fā)送指定Flag廣播的方式图云,達(dá)到應(yīng)用在未啟動(dòng)的情況下仍然能夠收到消息的效果。從Android 3.1開始邻邮,系統(tǒng)給Intent定義了兩個(gè)新的Flag竣况,分別為FLAGINCLUDESTOPPEDPACKAGES(表示包含未啟動(dòng)的App)和FLAGEXCLUDESTOPPEDPACKAGES(表示不包含未啟動(dòng)的App),用來(lái)控制Intent是否要對(duì)處于停止?fàn)顟B(tài)的App起作用筒严。

解決方案:只能借助其它應(yīng)用給自己發(fā)送帶FLAG_INCLUDESTOPPEDPACKAGES標(biāo)志的廣播才能實(shí)現(xiàn)在程序未啟動(dòng)的情況下接收到廣播丹泉;

android:windowBackground導(dǎo)致的過渡繪制問題:

問題現(xiàn)象:界面的布局已無(wú)法進(jìn)一步優(yōu)化,但仍然存在過渡繪制的問題鸭蛙;

原因分析:window存在默認(rèn)的背景摹恨,會(huì)增加過渡繪制的可能。Activity是依附在Window上的娶视,如果給Activity設(shè)置了背景晒哄,并且沒有去掉window的背景,很容易導(dǎo)致過渡繪制肪获;這里還有一個(gè)坑寝凌,有的應(yīng)用為了避免程序冷啟動(dòng)時(shí)出現(xiàn)黑屏/白屏的問題,在主題中給window設(shè)置了背景贪磺,并且在Activity的布局中給Activity也設(shè)置了背景硫兰,這會(huì)導(dǎo)致當(dāng)前界面存在兩個(gè)背景,占用了雙倍的內(nèi)存寒锚,并且還會(huì)有過渡繪制的問題劫映。程序啟動(dòng)黑屏應(yīng)該去優(yōu)化性能問題,而不是采用給window設(shè)置背景的方式刹前;

解決方案:可以通過給Activity自定義主題泳赋,在主題中去掉window的默認(rèn)背景,即:@null喇喉;

類的finalize方法調(diào)用時(shí)機(jī)不確定:

問題現(xiàn)象:程序隨機(jī)崩潰祖今;

原因分析:多個(gè)地方用到了同一個(gè)類,該類用于對(duì)數(shù)據(jù)的IO操作,打開文件后并沒有立即關(guān)閉千诬,也沒有釋放資源的public方法耍目,主要通過類的finalize方法關(guān)閉文件,釋放資源徐绑;

解決方案:finalize方法的調(diào)用時(shí)機(jī)是不確定的邪驮,不要指望通過該方法釋放與類相關(guān)的資源,避免出現(xiàn)隨機(jī)的bug傲茄;

Fragment isAdded:

問題現(xiàn)象:程序隨機(jī)崩潰毅访;

原因分析:跟蹤異常log發(fā)現(xiàn),是因?yàn)镕ragment沒有完全顯示或者已經(jīng)離開Fragment的情況下盘榨,導(dǎo)致的異常喻粹,這類異常的主要原因是:使用Fragment時(shí),通過異步操作(比如回調(diào)草巡、非UI線程等)更新Fragment的狀態(tài)守呜,但此時(shí)Fragment沒有完全顯示或者已經(jīng)離開Fragment;

解決方案:在調(diào)用Fragment的方法之前山憨,強(qiáng)烈建議調(diào)用isAdded方法判斷Fragment是否依附在Activity上弛饭,避免出現(xiàn)異常。

Fragment hide萍歉、show被調(diào)用時(shí)侣颂,生命周期不會(huì)回調(diào):

問題現(xiàn)象:同一界面不同F(xiàn)ragment之間切換時(shí),并沒有觸發(fā)一些動(dòng)態(tài)效果枪孩,比如播報(bào)音頻憔晒、顯示切換動(dòng)畫等;

原因分析:Fragment hide蔑舞、show被調(diào)用時(shí)拒担,系統(tǒng)并不會(huì)調(diào)用Fragment的生命周期回調(diào);

解決方案:不同F(xiàn)ragment之間切換時(shí)攻询,主動(dòng)調(diào)用各個(gè)Fragment的生命周期回調(diào)从撼;

項(xiàng)目中遇到的坑

9圖不要用tinypng壓縮:

問題現(xiàn)象:使用壓縮工具壓縮9圖后,顯示變形钧栖;

原因分析:9圖除了圖片信息外低零,還存儲(chǔ)一些Android在顯示9圖過程中需要用到的必要信息,通過壓縮工具壓縮圖片會(huì)改變文件的信息拯杠,9圖被壓縮后程序能顯示掏婶,但顯示的效果無(wú)法達(dá)到預(yù)期,因?yàn)槔煨畔G失了潭陪。

解決方案:9圖文件本身就不大雄妥,沒必要壓縮最蕾;

同一設(shè)備上,相同程序的圖片放在不同drawable文件夾下老厌,占用內(nèi)存不一樣:

問題現(xiàn)象:程序剛啟動(dòng)就占用了很高的內(nèi)存瘟则;

原因分析:圖片放置位置不合理導(dǎo)致的,程序在不同的設(shè)備中運(yùn)行時(shí)枝秤,會(huì)根據(jù)設(shè)備的分辨率和屏幕密度去從與之分辨率匹配的資源文件夾中取圖片壹粟,如果沒有對(duì)應(yīng)分辨率的文件夾,則從相近分辨率的文件夾中取宿百,但圖片會(huì)被拉伸到當(dāng)前設(shè)備屏幕的寬高,所以會(huì)存在圖片被放大或者縮小的問題洪添,導(dǎo)致占用內(nèi)存會(huì)隨之變化垦页,具體可以查看這篇博客關(guān)于Android中圖片大小、內(nèi)存占用與drawable文件夾關(guān)系的研究與分析(http://blog.csdn.net/zhaokaiqiang1992/article/details/49787117)干奢;

解決方案:為了減少UI的工作量痊焊,并且減少APK的內(nèi)存占用的方法是讓UI出一套高分辨率版本的圖片,放在hdpi文件夾下忿峻。

Adapter ViewHolder緩存導(dǎo)致顯示錯(cuò)亂的坑:

問題現(xiàn)象:ListView每一項(xiàng)在滑動(dòng)的過程中內(nèi)容顯示錯(cuò)亂薄啥;

原因分析:在Adapter的getView方法中通過position更新每一項(xiàng)的內(nèi)容時(shí),對(duì)于根據(jù)判斷條件給每一項(xiàng)設(shè)置屬性的情況逛尚,每個(gè)判斷條件下都需要給每一項(xiàng)的每個(gè)屬性賦值垄惧,否則在滑動(dòng)ListView或GridView時(shí)會(huì)導(dǎo)致內(nèi)容錯(cuò)亂;

解決方案:在getView方法里面绰寞,給每一項(xiàng)都要設(shè)置對(duì)應(yīng)的屬性到逊,比如給每一項(xiàng)的頭像設(shè)置圖片,如果某一項(xiàng)沒有頭像滤钱,不能不設(shè)置觉壶,應(yīng)該設(shè)置為透明,否則會(huì)錯(cuò)亂件缸。

Toast連續(xù)顯示時(shí)長(zhǎng)時(shí)間不消失:

問題現(xiàn)象:多個(gè)Toast同時(shí)顯示時(shí)铜靶,Toast一直顯示不消失,退出程序了仍然顯示他炊;

原因分析:看Toast的源碼可以發(fā)現(xiàn)争剿,同時(shí)顯示多個(gè)toast時(shí)是排隊(duì)顯示的,所以才會(huì)出現(xiàn)同時(shí)顯示多個(gè)Toast時(shí)很久都不消失的情況痊末;

解決方案:這屬于體驗(yàn)問題秒梅,很多應(yīng)用都存在。建議定義一個(gè)全局的Toast對(duì)象舌胶,這樣可以避免連續(xù)顯示Toast時(shí)不能取消上一次Toast消息的情況(如果你有連續(xù)彈出Toast的情況捆蜀,避免使用Toast.makeText);

build.gradle中的versionName和versionCode:

問題現(xiàn)象:從Eclipse轉(zhuǎn)到AS的項(xiàng)目,在機(jī)器上運(yùn)行時(shí)報(bào)版本比之前APK版本低的錯(cuò)誤辆它;

原因分析:從Eclipse轉(zhuǎn)到AS的過程中誊薄,如果你是通過AS直接新創(chuàng)建的一個(gè)工程,注意模板會(huì)在build.gradle中給程序設(shè)置默認(rèn)versionName和versionCode為1锰茉,如果AndroidManifest.xml中的versionCode呢蔫、versionName比build.gradle中的更高,會(huì)導(dǎo)致因?yàn)榘姹締栴}安裝不上的情況(報(bào)INSTALL_FAILEDVERSIONDOWNGRADE錯(cuò)誤)飒筑;

解決方案:只在build.gradle中設(shè)置版本名和版本號(hào)片吊;

AS中依賴包的動(dòng)態(tài)更新:

問題現(xiàn)象:依賴包頻繁更新,因?yàn)锳S編譯有緩存协屡,每次更新都需要修改依賴包的版本號(hào)俏脊,特別麻煩,特別是依賴關(guān)系比較復(fù)雜的情況下肤晓;

解決方案:在AS中爷贫,如果你想動(dòng)態(tài)同步一個(gè)依賴包的更新,可以在依賴包的最后面寫上“+”补憾,比如:compile 'com.android.support:appcompat-v7:23.0.+' 漫萄,但這種方法需要謹(jǐn)慎使用,否則會(huì)因?yàn)橐蕾嚢淖儎?dòng)導(dǎo)致你的項(xiàng)目不穩(wěn)定:Don't use dynamic versions for your dependencies(https://link.zhihu.com/?target=http%3A//blog.danlew.net/2015/09/09/dont-use-dynamic-versions-for-your-dependencies/)盈匾;

AS中同一個(gè)工程module太多導(dǎo)致編譯慢:

問題現(xiàn)象:編譯一個(gè)工程要好幾分鐘腾务,特別是clean的時(shí)候,經(jīng)常10分鐘以上削饵;

原因分析:其實(shí)這個(gè)很好理解窑睁,每個(gè)module中都有一個(gè)build.gradle,編譯的時(shí)候葵孤,每個(gè)module的build.gradle中的task都需要執(zhí)行担钮,所以編譯時(shí)間會(huì)很長(zhǎng)。

解決方案:要解決這個(gè)問題很簡(jiǎn)單尤仍,將不經(jīng)常變動(dòng)的module打包成aar箫津,主工程依賴aar而不是module,這樣避免了每次都需要重新編譯module的情況宰啦。

頻繁的GC操作導(dǎo)致程序卡頓:

問題現(xiàn)象:通過AS Monitor觀察應(yīng)用運(yùn)行過程中的內(nèi)存抖動(dòng)厲害苏遥,通過GPU呈現(xiàn)模式觀察每一幀的曲線差別很大,整體感受程序運(yùn)行時(shí)不流暢赡模;

原因分析:在2.3之前GC操作是不能并發(fā)進(jìn)行的田炭,也就是系統(tǒng)正在進(jìn)行GC程序就只能阻塞住等待GC結(jié)束,在2.3之后GC操作改成了并發(fā)的方式進(jìn)行漓柑,GC過程中不會(huì)影響程序的正常運(yùn)行教硫,但在GC操作的開始和結(jié)束還是會(huì)短暫阻塞一段時(shí)間叨吮,所以頻繁的GC會(huì)導(dǎo)致使用應(yīng)用的過程中卡頓。

解決方案:為了應(yīng)用在使用過程中更流暢瞬矩,需要盡量減少觸發(fā)GC操作茶鉴,這涉及到性能優(yōu)化,對(duì)于靜態(tài)代碼的分析景用,AS已經(jīng)很強(qiáng)大了涵叮,可以使用Android Studio的Analyze→Inspect Code...進(jìn)行分析;

TextView 的setText方法伞插,如果傳入一個(gè)數(shù)字會(huì)直接當(dāng)作字符串資源ID處理:

問題現(xiàn)象:程序運(yùn)行時(shí)報(bào)“NotFoundException”異常割粮;

原因分析:TextView.setText(int value)的傳值有問題,在xml文件中沒有找到id對(duì)應(yīng)的字符串媚污;

解決方案:給TextView設(shè)置文本的時(shí)候一定要轉(zhuǎn)成String或者Charsequence類型舀瓢,避免TextView將setText中的參數(shù)當(dāng)做字符串資源ID處理,去加載字符串資源杠步,因?yàn)樽址趚ml文件中不存在導(dǎo)致程序運(yùn)行時(shí)崩潰。

通過反射訪問方法和字段的效率大不一樣:

問題現(xiàn)象:程序運(yùn)行卡榜轿、慢幽歼;

原因分析:在一個(gè)循環(huán)中使用到了反射,并且是調(diào)用的反射方法谬盐,改成反射字段后甸私,卡、慢的現(xiàn)象得到明顯的改善飞傀;

解決方案:通過反射修改或者獲取類中的某個(gè)屬性時(shí)皇型,強(qiáng)烈建議使用訪問字段的方式,不要使用訪問方法的方式砸烦,這兩者之間的效率相差很大弃鸦,親測(cè)訪問方法是訪問字段耗時(shí)的1.5倍,具體情況和類的復(fù)雜度有關(guān)幢痘。

.nomedia文件的使用:

問題現(xiàn)象:程序中的緩存文件在相冊(cè)唬格、音樂播放器中顯示;

原因分析:相冊(cè)颜说、音樂播放器等多媒體應(yīng)用是讀取媒體庫(kù)中的數(shù)據(jù)购岗,而程序的緩存文件被緩存到了媒體數(shù)據(jù)庫(kù)中;

解決方案:如果你希望自己應(yīng)用生成的數(shù)據(jù)不被媒體庫(kù)掃描到门粪,應(yīng)該在生成數(shù)據(jù)的文件夾下創(chuàng)建一個(gè)名為".nomedia"的隱藏文件喊积,避免出現(xiàn)一些無(wú)意義的文件也被媒體庫(kù)掃描到的情況,比如APP的緩存圖片在相冊(cè)中顯示玄妈、宣傳視頻在視頻播放器中顯示乾吻、音效在音樂播放器中顯示等髓梅。

循環(huán)動(dòng)畫:

問題現(xiàn)象:在不待機(jī)的情況下,長(zhǎng)時(shí)間處于一個(gè)界面時(shí)溶弟,手機(jī)發(fā)燙女淑;

原因分析:界面中存在循環(huán)動(dòng)畫,CPU辜御、GPU一直在工作鸭你;

解決方案:循環(huán)動(dòng)畫會(huì)導(dǎo)致界面一直在刷新,CPU擒权、GPU持續(xù)工作袱巨,會(huì)有功耗問題,在界面銷毀的地方清除動(dòng)畫碳抄。

謹(jǐn)慎使用aaptOptions.cruncherEnabled = false;aaptOptions.useNewCruncher = false;

問題現(xiàn)象:編譯生成的APK文件特別大愉老,超過了正常的大小剖效;

原因分析:解壓APK發(fā)現(xiàn)嫉入,主要是圖片資源導(dǎo)致,將APK中的res文件夾和源碼下的res文件夾對(duì)比璧尸,發(fā)現(xiàn)多了很多圖片文件咒林;跟蹤原因發(fā)現(xiàn)最新的buildtools對(duì)資源文件的檢測(cè)很嚴(yán)格,對(duì)于Eclipse轉(zhuǎn)AS的項(xiàng)目爷光,很多時(shí)候都是因?yàn)閳D片問題導(dǎo)致在AS上編譯不過垫竞,比如將jpg強(qiáng)轉(zhuǎn)為png在AS上就編譯不過,在項(xiàng)目中可以在build.gradle中加上這兩句:aaptOptions.cruncherEnabled = false;aaptOptions.useNewCruncher = false蛀序,屏蔽掉aapt對(duì)圖片的嚴(yán)格檢測(cè)欢瞪。但需要謹(jǐn)慎使用這兩個(gè)屬性,否則可能會(huì)導(dǎo)致編譯生成的APK特別大(解壓生成后的APK發(fā)現(xiàn)徐裸,對(duì)于有問題的圖片遣鼓,每個(gè)drawable文件夾下都會(huì)拷貝一份);

解決方案:去掉屬性設(shè)置重贺,解決編譯問題譬正。

開源項(xiàng)目中的坑

EventBus:

問題現(xiàn)象:搜索商品的時(shí)候,不顯示搜索結(jié)果檬姥;

原因分析:FragmentActivity包含四個(gè)碎片F(xiàn)ragment曾我,在FragmentActivity中點(diǎn)擊搜索按鈕要向Fragment發(fā)送消息顯示碎片界面并執(zhí)行搜索任務(wù),消息沒有發(fā)送成功健民,但是測(cè)試發(fā)現(xiàn)當(dāng)界面顯示后再發(fā)送抒巢,消息可以正常接收;

解決方案:把Fragment的根布局從GONE該為Invisible秉犹,發(fā)現(xiàn)消息可以正常接收蛉谜,所以總結(jié)原因是EventBus消息接收前提是不能為GONE稚晚。


問題現(xiàn)象:在Fragment注冊(cè)EventBus報(bào)錯(cuò);

原因分析:Fragment注冊(cè)EventBus時(shí)要傳遞一個(gè)上下文參數(shù)型诚,寫成了Fragment上下文getActivity()運(yùn)行后報(bào)錯(cuò)客燕,說我Fragment的父Activity沒有對(duì)應(yīng)接收消息的方法;

解決方案:把getActivity()改成this狰贯。

Glide:

問題現(xiàn)象:加載gif很慢或者加載不出來(lái)也搓;

原因分析:Glide加載gif圖是一幀一幀加載的,gif過大就會(huì)加載慢涵紊;

解決方案:加入緩存策略傍妒,Glide.with(this).load(url).asGif().diskCacheStrategy(DiskCacheStrategy.SOURCE).into(imageView),還可以控制gif顯示次數(shù)Glide.with(this).load("url").diskCacheStrategy(DiskCacheStrategy.SOURCE).into(new GlideDrawableImageViewTarget(iv,1))摸柄。

FancyCoverFlow:這個(gè)控件在API高于16的設(shè)備中颤练,滑動(dòng)的過程中會(huì)強(qiáng)制刷新一遍,導(dǎo)致切換和初始化的時(shí)候都很卡驱负,當(dāng)時(shí)覺得這個(gè)效果挺好嗦玖,后來(lái)用上之后這個(gè)控件成了性能瓶頸;

Fresco:這個(gè)控件用起來(lái)特別爽跃脊,唯一的缺陷的相比于相同功能的其它開源項(xiàng)目(Glide宇挫、Picasso),體積過大匾乓;

ActiveAndroid:這個(gè)輕量級(jí)的數(shù)據(jù)庫(kù)框架也挺好用捞稿,但缺陷是初始化耗時(shí)又谋,可以看一下這篇文章:在Android中使用反射到底有多慢拼缝?

JXL:一個(gè)讀寫Excel文件的開源庫(kù),用起來(lái)很方便彰亥,但有個(gè)問題:文件大小超過5M直接掛掉咧七;

JPinyin:漢字轉(zhuǎn)拼音的一個(gè)工具庫(kù),APK加密后這個(gè)庫(kù)不能正常使用任斋,后來(lái)查出是因?yàn)轫?xiàng)目中數(shù)據(jù)的問題继阻,加密后數(shù)據(jù)的內(nèi)容變化了,最后只能自己改造废酷,將數(shù)據(jù)按照我們自己的方式處理瘟檩。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市澈蟆,隨后出現(xiàn)的幾起案子墨辛,更是在濱河造成了極大的恐慌,老刑警劉巖趴俘,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件睹簇,死亡現(xiàn)場(chǎng)離奇詭異奏赘,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)太惠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門磨淌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人凿渊,你說我怎么就攤上這事梁只。” “怎么了嗽元?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵敛纲,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我剂癌,道長(zhǎng)淤翔,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任佩谷,我火速辦了婚禮旁壮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘谐檀。我一直安慰自己抡谐,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布桐猬。 她就那樣靜靜地躺著麦撵,像睡著了一般。 火紅的嫁衣襯著肌膚如雪溃肪。 梳的紋絲不亂的頭發(fā)上免胃,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音惫撰,去河邊找鬼羔沙。 笑死,一個(gè)胖子當(dāng)著我的面吹牛厨钻,可吹牛的內(nèi)容都是我干的扼雏。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼夯膀,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼诗充!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起诱建,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蝴蜓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后涂佃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體励翼,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蜈敢,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了汽抚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抓狭。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖造烁,靈堂內(nèi)的尸體忽然破棺而出否过,到底是詐尸還是另有隱情,我是刑警寧澤惭蟋,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布苗桂,位于F島的核電站,受9級(jí)特大地震影響告组,放射性物質(zhì)發(fā)生泄漏煤伟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一木缝、第九天 我趴在偏房一處隱蔽的房頂上張望便锨。 院中可真熱鬧,春花似錦我碟、人聲如沸放案。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)吱殉。三九已至,卻和暖如春厘托,著一層夾襖步出監(jiān)牢的瞬間友雳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工催烘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留沥阱,地道東北人缎罢。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓伊群,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親策精。 傳聞我的和親對(duì)象是個(gè)殘疾皇子舰始,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,099評(píng)論 25 707
  • 這些坑主要分為幾個(gè)類:分為系統(tǒng)API的坑、使用不當(dāng)導(dǎo)致的坑咽袜、開源項(xiàng)目中的坑等幾個(gè)方面 1.系統(tǒng)API的坑## (1...
    AlexanderPhaf閱讀 2,829評(píng)論 0 4
  • ㈠ 第一世·遇見 遇見李和是在冬天询刹。 別人都說李家二公子谜嫉,才高八斗溫文爾雅萎坷。 我只知道救我的時(shí)候,他的手心很暖沐兰。 ...
    七月流火_850e閱讀 382評(píng)論 3 12
  • 都說傻瓜最快樂哆档,因?yàn)樯倒鲜裁词虑槎疾粫?huì)放在心上。 可能很多人都忘記9年前的今天一場(chǎng)大地震突然降臨在四川住闯,短短幾分鐘...
    朋友喜歡叫我春哥閱讀 215評(píng)論 0 0
  • 我總覺得在人漫長(zhǎng)的一生中學(xué)會(huì)不討人厭是件比學(xué)會(huì)如何討人喜歡更重要的事情瓜浸。 這兩年接觸旅游業(yè),說實(shí)話并不算多喜歡比原,因...
    惘聞_閱讀 272評(píng)論 0 4