阿里的android開發(fā)規(guī)范已經(jīng)出來有幾個(gè)月了盹牧,不過今天我才看俩垃,看完后對(duì)自己以前不夠規(guī)范或者容易犯錯(cuò)的地方進(jìn)行筆記記錄便于以后查閱。
原版手冊(cè)地址:https://yq.aliyun.com/attachment/download/?id=5261
一? Android基本組件
【強(qiáng)制】Activity間通過隱式Intent的跳轉(zhuǎn)汰寓,在發(fā)出Intent之前必須通過resolveActivity 檢查口柳,避免找不到合適的調(diào)用組件,造成ActivityNotFoundException 的異常有滑。
正例:
public void viewUrl(String url, String mimeType) {
? ? Intent intent = new Intent(Intent.ACTION_VIEW);
? ? intent.setDataAndType(Uri.parse(url), mimeType);
? ? if (getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ ONLY) != null) {
? ? ? ? startActivity(intent);
? ? ? }else {
? ? ? // 找不到指定的Activity
? ? }
}
反例:
Intent intent = new Intent();
intent.setAction("com.example.DemoIntent ");
try {
? ? startActivity(intent); } catch (ActivityNotFoundException e) {
? ? e.printStackTrace();
}?
5. 【強(qiáng)制】避免在BroadcastReceiver#onReceive()中執(zhí)行耗時(shí)操作跃闹,如果有耗時(shí)工作, 應(yīng)該創(chuàng)建IntentService 完成毛好,而不應(yīng)該在BroadcastReceiver 內(nèi)創(chuàng)建子線程去做望艺。
說明:
由于該方法是在主線程執(zhí)行,如果執(zhí)行耗時(shí)操作會(huì)導(dǎo)致 UI 不流暢肌访≌夷可以使用 IntentService 、創(chuàng)建 HandlerThread 或者調(diào)用 Context#registerReceiver (BroadcastReceiver, IntentFilter, String, Handler)方法等方式吼驶,在其他Wroker線程 執(zhí)行 onReceive 方法惩激。BroadcastReceiver#onReceive()方法耗時(shí)超過 10 秒鐘,可 能會(huì)被系統(tǒng)殺死蟹演。
6. 【強(qiáng)制】避免使用隱式 Intent 廣播敏感信息风钻,信息可能被其他注冊(cè)了對(duì)應(yīng) BroadcastReceiver的App接收。
說明:
通過Context#sendBroadcast()發(fā)送的隱式廣播會(huì)被所有感興趣的receiver接收酒请,惡 意應(yīng)用注冊(cè)監(jiān)聽該廣播的 receiver 可能會(huì)獲取到 Intent 中傳遞的敏感信息骡技,并進(jìn)行 其他危險(xiǎn)操作。如果發(fā)送的廣播為使用 Context#sendOrderedBroadcast()方法發(fā)送 的有序廣播蚌父,優(yōu)先級(jí)較高的惡意 receiver 可能直接丟棄該廣播哮兰,造成服務(wù)不可用, 或者向廣播結(jié)果塞入惡意數(shù)據(jù)苟弛。
如果廣播僅限于應(yīng)用內(nèi)喝滞,則可以使用 LocalBroadcastManager#sendBroadcast()實(shí) 現(xiàn),避免敏感信息外泄和Intent攔截的風(fēng)險(xiǎn)膏秫。
8. 【推薦】不要在 Activity#onDestroy()內(nèi)執(zhí)行釋放資源的工作右遭,例如一些工作線程的 銷毀和停止,因?yàn)?onDestroy()執(zhí)行的時(shí)機(jī)可能較晚缤削【焦可根據(jù)實(shí)際需要,在 Activity#onPause()/onStop()中結(jié)合isFinishing()的判斷來執(zhí)行亭敢。
11.【推薦】Service 需要以多線程來并發(fā)處理多個(gè)啟動(dòng)請(qǐng)求滚婉,建議使用 IntentService, 可避免各種復(fù)雜的設(shè)置帅刀。
說
13.【推薦】當(dāng)前 Activity 的 onPause 方法執(zhí)行結(jié)束后才會(huì)創(chuàng)建(onCreate)或恢復(fù) (onRestart)別的Activity让腹,所以在onPause方法中不適合做耗時(shí)較長(zhǎng)的工作远剩,這 會(huì)影響到頁(yè)面之間的跳轉(zhuǎn)效率。
二 UI與布局
2. 【推薦】在 Activity 中顯示對(duì)話框或彈出浮層時(shí)骇窍,盡量使用 DialogFragment瓜晤,而非 Dialog/AlertDialog,這樣便于隨Activity生命周期管理對(duì)話框/彈出浮層的生命周期
5. 【推薦】文本大小使用單位 dp腹纳,View 大小使用單位 dp痢掠。對(duì)于 TextView,如果在文 字大小確定的情況下推薦使用 wrap_content 布局避免出現(xiàn)文字顯示不全的適配問 題嘲恍。
說明:
之所以文本大小也推薦使用dp而非sp足画,因?yàn)閟p是Android早期推薦使用的,但其 實(shí) sp 不僅和 dp 一樣受屏幕密度的影響佃牛,還受到系統(tǒng)設(shè)置里字體大小的影響锌云,所以 使用dp對(duì)于應(yīng)用開發(fā)會(huì)更加保證UI的一致性和還原度
10.【推薦】盡量不要使用 AnimationDrawable,它在初始化的時(shí)候就將所有圖片加載 到內(nèi)存中吁脱,特別占內(nèi)存,并且還不能釋放彬向,釋放之后下次進(jìn)入再次加載時(shí)會(huì)報(bào)錯(cuò)兼贡。
說明:
Android 的幀動(dòng)畫可以使用 AnimationDrawable 實(shí)現(xiàn),但是如果你的幀動(dòng)畫中如果 包含過多幀圖片娃胆,一次性加載所有幀圖片所導(dǎo)致的內(nèi)存消耗會(huì)使低端機(jī)發(fā)生 OOM 異常遍希。幀動(dòng)畫所使用的圖片要注意降低內(nèi)存消耗,當(dāng)圖片比較大時(shí)里烦,容易出現(xiàn)OOM凿蒜。
11.【強(qiáng)制】不能使用 ScrollView 包裹 ListView/GridView/ExpandableListVIew;因?yàn)檫@ 樣會(huì)把 ListView 的所有 Item 都加載到內(nèi)存中,要消耗巨大的內(nèi)存和 cpu 去繪制圖 面胁黑。
說明:
ScrollView中嵌套List或RecyclerView的做法官方明確禁止废封。除了開發(fā)過程中遇到 的各種視覺和交互問題,這種做法對(duì)性能也有較大損耗丧蘸。ListView等UI組件自身有 垂直滾動(dòng)功能漂洋,也沒有必要在嵌套一層ScrollView。目前為了較好的UI體驗(yàn)力喷,更貼 近Material Design的設(shè)計(jì)刽漂,推薦使用NestedScrollView
12.【強(qiáng)制】不要在 Android 的 Application 對(duì)象中緩存數(shù)據(jù)〉苊希基礎(chǔ)組件之間的數(shù)據(jù)共享 請(qǐng)使用Intent等機(jī)制贝咙,也可使用SharedPreferences等數(shù)據(jù)持久化機(jī)制。
13.【推薦】使用 Toast 時(shí)拂募,建議定義一個(gè)全局的 Toast 對(duì)象庭猩,這樣可以避免連續(xù)顯示 Toast時(shí)不能取消上一次Toast消息的情況窟她。即使需要連續(xù)彈出Toast,也應(yīng)避免直 接調(diào)用Toast#makeText眯娱。
五礁苗、進(jìn)程、線程與消息通信
1. 【強(qiáng)制】不要通過 Intent 在 Android 基礎(chǔ)組件之間傳遞大數(shù)據(jù)(binder transaction 緩存為1MB)徙缴,可能導(dǎo)致OOM试伙。
2. 【強(qiáng)制】在 Application 的業(yè)務(wù)初始化代碼加入進(jìn)程判斷,確保只在自己需要的進(jìn)程 初始化于样。特別是后臺(tái)進(jìn)程減少不必要的業(yè)務(wù)初始化疏叨。
3. 【強(qiáng)制】新建線程時(shí),必須通過線程池提供(AsyncTask 或者 ThreadPoolExecutor 或者其他形式自定義的線程池)穿剖,不允許在應(yīng)用中自行顯式創(chuàng)建線程蚤蔓。
說明:
使用線程池的好處是減少在創(chuàng)建和銷毀線程上所花的時(shí)間以及系統(tǒng)資源的開銷,解 決資源不足的問題糊余。如果不使用線程池秀又,有可能造成系統(tǒng)創(chuàng)建大量同類線程而導(dǎo)致消耗完內(nèi)存或者“過度切換”的問題。另外創(chuàng)建匿名線程不便于后續(xù)的資源使用分析贬芥, 對(duì)性能分析等會(huì)造成困擾吐辙。
4. 【強(qiáng)制】線程池不允許使用Executors去創(chuàng)建,而是通過ThreadPoolExecutor的方 式蘸劈,這樣的處理方式讓寫的同學(xué)更加明確線程池的運(yùn)行規(guī)則昏苏,規(guī)避資源耗盡的風(fēng)險(xiǎn)。
七威沫、Bitmap贤惯、Drawable與動(dòng)畫
6. 【強(qiáng)制】在Activity#onPause()或Activity#onStop()回調(diào)中,關(guān)閉當(dāng)前activity正在執(zhí) 行的的動(dòng)畫
9.【推薦】使用 RGB_565 代替 RGB_888棒掠,在不怎么降低視覺效果的前提下孵构,減少內(nèi) 存占用
10.【推薦】盡量減少Bitmap(BitmapDrawable)的使用,盡量使用純色(ColorDrawable)句柠、 漸變色(GradientDrawable)浦译、 StateSelector(StateListDrawable)等與 Shape 結(jié) 合的形式構(gòu)建繪圖
12.【參考】大圖片資源不要直接打包到apk,可以考慮通過文件倉(cāng)庫(kù)遠(yuǎn)程下載溯职,減小包 體積精盅。