??最近正準(zhǔn)備寫一篇關(guān)于這方面的文章,正好看到知乎上的這個(gè)問(wèn)題:Android 開(kāi)發(fā)中,有哪些坑需要注意? - Android,索性以寫答案的方式來(lái)寫這篇文章,順便推薦我之前在知乎上提出的一個(gè)問(wèn)題:在Android開(kāi)發(fā)的過(guò)程中,有哪些坑是值得你放在checklist中警示自己的? - 程序員,里面有一些有參考價(jià)值的答案。
??作為一個(gè)有三、四年Android應(yīng)用開(kāi)發(fā)經(jīng)驗(yàn)的碼農(nóng),自然會(huì)遇到很多坑,下面是我能夠想起的一些坑(實(shí)踐證明不記筆記可不是個(gè)好習(xí)慣),后面有想到其它坑會(huì)陸續(xù)補(bǔ)上。
在Android library中不能使用switch-case語(yǔ)句訪問(wèn)資源ID:在Android library中不能使用switch-case語(yǔ)句訪問(wèn)資源ID的原因分析及解決方案**
不能在Activity沒(méi)有完全顯示時(shí)顯示PopupWindow和Dialog:popupwindow - Problems creating a Popup Window in Android Activity**
在多進(jìn)程之間不要用SharedPreferences共享數(shù)據(jù),雖然可以(MODE_MULTI_PROCESS),但極不穩(wěn)定:android - MODE_MULTI_PROCESS for SharedPreferences isn't working**
有些時(shí)候不能使用Application的Context,不然會(huì)報(bào)錯(cuò)(比如啟動(dòng)Activity,顯示Dialog等):
同一個(gè)應(yīng)用的JNI代碼,不要輕易換NDK編譯的版本,否則會(huì)有很多問(wèn)題(主要是一些方法實(shí)現(xiàn)不一樣,并且高版本對(duì)代碼的檢測(cè)更嚴(yán)格),比如r8沒(méi)有問(wèn)題,但到r9就有問(wèn)題了,這是個(gè)大坑;
Android的JNI代碼中,有返回類型的函數(shù)沒(méi)有返回值編譯的時(shí)候也不會(huì)報(bào)錯(cuò);
當(dāng)前Activity的onPause方法執(zhí)行結(jié)束后才會(huì)執(zhí)行下一個(gè)Activity的onCreate方法,所以在onPause方法中不適合做耗時(shí)較長(zhǎng)的工作,這會(huì)影響到頁(yè)面之間的跳轉(zhuǎn)效率;
謹(jǐn)慎使用Android的透明主題,透明主題會(huì)導(dǎo)致很多問(wèn)題,比如:如果新的Activity采用了透明主題,那么當(dāng)前Activity的onStop方法不會(huì)被調(diào)用;在設(shè)置為透明主題的Activity界面按Home鍵時(shí),可能會(huì)導(dǎo)致刷屏不干凈的問(wèn)題;進(jìn)入主題為透明主題的界面會(huì)有明顯的延時(shí)感;
不要在非UI線程中初始化ViewStub,否則會(huì)返回null;
公共接口一定要考慮到代碼重入的情況,能設(shè)計(jì)為單例就盡量用單例;
不要通過(guò)Bundle傳遞大塊的數(shù)據(jù),否則會(huì)報(bào)TransactionTooLargeException異常:java - Issue: Passing large data to second Activity**
盡量不要通過(guò)Application緩存數(shù)據(jù),這不穩(wěn)定:不要在Android的Application對(duì)象中緩存數(shù)據(jù)!**
盡量不要使用AnimationDrawable,它在初始化的時(shí)候就將所有圖片加載到內(nèi)存中,特別占內(nèi)存,并且還不能釋放,釋放之后下次進(jìn)入再次加載時(shí)會(huì)報(bào)錯(cuò);
9圖不能通過(guò)tinypng壓縮,不然會(huì)有問(wèn)題;
genymotion模擬器快是因?yàn)樗腔趚86架構(gòu)的,如果你的應(yīng)用中用到了so,但沒(méi)有x86架構(gòu)的so,只能放棄使用它;Android Studio的模擬器也一樣;
Eclipse的Android開(kāi)發(fā)環(huán)境配置好后不要輕易升級(jí)ADT和build tools,不然會(huì)浪費(fèi)你很多時(shí)間,還有就是一個(gè)workspace中的工程不要太多,不然每次啟動(dòng)都會(huì)很慢;
Android studio每個(gè)版本、gradle每個(gè)版本差別都比較大(我是這樣認(rèn)為的),對(duì)于jni代碼的編譯建議在Eclipse中進(jìn)行,如果在Android studio中開(kāi)發(fā)jni會(huì)浪費(fèi)很多時(shí)間,主要是編譯腳本的配置比較麻煩;
Eclipse中的Lint太不靠譜,特別是主工程中依賴library的時(shí)候,很多提示都是有問(wèn)題的,建議使用Android Studio的工程清理工具,特別推薦。
AsyncTask默認(rèn)自己維護(hù)一個(gè)靜態(tài)的線程池,而該線程池只允許同時(shí)執(zhí)行一個(gè)線程,也就是說(shuō),不管多少個(gè)AsyncTask,只要是調(diào)用execute()方法,都是共享這個(gè)默認(rèn)進(jìn)程池的,你的任務(wù)必須在之前的任務(wù)執(zhí)行完以后,才能執(zhí)行。調(diào)用AsyncTask的excute方法不能立即執(zhí)行程序的原因分析及改善方案**