Android開發(fā)注意事項(xiàng)

以下總結(jié)全部來源于開發(fā)經(jīng)驗(yàn)積累嘶窄,干貨滿滿的别瞭,有問題請郵箱1057915589@qq.com策严,感謝!敬禮~

1凑保、安卓xml命名:比如以音樂模塊為例
music_activity.xml冈爹、music_fragment.xml欧引、music_dialog.xml、music_list_item.xml芝此、

music_recycle_item.xml憋肖、music_grid_item.xml等

2、資源文件命名:登錄按鈕背景資源圖片(模塊名_功能_控件描述_控件限定詞)

base_login_btn_pressed.png婚苹、base_login_btn_normal.png

3岸更、顏色由于是整個(gè)app共用的,所以我不太同意阿里規(guī)約的命名方式膊升,我感覺可以寫一套直接根據(jù)色值查找更合理

比如:白色<color name="color_ffffff">#ffffff</color> 只需要命名一套即可

4坐慰、控件命名可以使用控件名稱縮寫作為前綴,如下:

LinearLayout對應(yīng)ll、RelativeLayout對應(yīng)rl结胀、ConstraintLayout對應(yīng)cl赞咙、ListView對應(yīng)lv

ScollView對應(yīng)sv、TextView對應(yīng)tv糟港、Button對應(yīng)btn攀操、ImageView對應(yīng)iv、CheckBox對應(yīng)cb

RadioButton對應(yīng)rb秸抚、EditText對應(yīng)et

5速和、Android的四大組件:Activity、Fragment剥汤、Service颠放、BroadcastReceiver

Activity間通信可以考慮EventBus,避免數(shù)據(jù)太大報(bào)TransactionTooLargeException

Activity的onSaveInstanceState()方法不是生命周期方法吭敢,不保證一定會(huì)被調(diào)用碰凶,它是Activity意外被銷毀保存Ui狀態(tài)的,只能用于臨時(shí)保存數(shù)據(jù)鹿驼,持久化存儲應(yīng)該放在onPause欲低、onStop中

6、Activity間隱式跳轉(zhuǎn)畜晰,在發(fā)出Intent之前要通過resolveActivity檢查目標(biāo)組件能否找到砾莱,避免報(bào)ActivityNotFoundException的異常,比如:

?if(getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ ONLY) !=null) {

..................

}

7凄鼻、Service的onStartCommand()腊瑟、onBind()不能執(zhí)行耗時(shí)操作,如果需要應(yīng)改用IntentService或者采用異步機(jī)制完成

8块蚌、避免在BroadcastReceiver的onReceiver()中執(zhí)行耗時(shí)操作扫步,可以通過創(chuàng)建IntentService完成

9、Context的sendBroadcast()發(fā)送隱式廣播會(huì)被所有感興趣的receiver接收匈子,避免敏感信息泄露,廣播可以僅限于應(yīng)用內(nèi)闯袒,可以使用LocalBroadcastManager的sendBroadcast()方法,避免敏感信息外泄和Intent攔截風(fēng)險(xiǎn)其徙,比如:

Intent intent = new Intent("my-sensitive-event");

intent.putExtra("event", "this is a test event");

LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

10、不要在Activity的onDestory()內(nèi)執(zhí)行釋放工作唾那,比如線程的銷毀闹获、停止,由于onDestory()執(zhí)行的時(shí)機(jī)比較晚龟虎,可以按實(shí)際需要結(jié)合ifFinishing()判斷在Activity的onPause()鲤妥、onStop()中

11棉安、Service組件運(yùn)行在主線程中,避免耗時(shí)操作贡耽,如果有耗時(shí)操作可以使用IntentService執(zhí)行后臺任務(wù)

12菇爪、當(dāng)前Activity的onPause方法執(zhí)行結(jié)束后會(huì)執(zhí)行下一個(gè)Activity的onCreate方法凳宙,所以onPause方法中不適合執(zhí)行耗時(shí)工作氏涩,會(huì)影響頁面間跳轉(zhuǎn)效率是尖。

13饺汹、不要在Application對象緩存全局?jǐn)?shù)據(jù),盡量用Intent傳遞或者SharedPreferences數(shù)據(jù)持久化機(jī)制

14兜辞、Activity或者Fragment中動(dòng)態(tài)注冊的BroadCastReceiver時(shí)逸吵,registerReceiver()和unregisterReceiver()要成對出現(xiàn)

15扫皱、布局盡量扁平化韩脑,防止View渲染經(jīng)過measure扰才、layout衩匣、draw消耗過多時(shí)間,盡量控制每一幀在16毫秒內(nèi)繪制完成生百。

16蚀浆、禁止在布局中多次設(shè)置子View和父View中為同樣的背景造成過度繪制

17市俊、盡量不要使用AnimationDrawable,它在初始化的時(shí)候?qū)⑺袌D片加載到內(nèi)存中滤奈,特別占內(nèi)存蜒程,并且還不能釋放昭躺,容易內(nèi)存溢出

18、不要使用ScrollView包裹LIstView/GridView/ExpandableListView偶垮,因?yàn)樗鼤?huì)把ListView的所有Item都加載到內(nèi)存中似舵,要消耗巨大的內(nèi)存與CPU去繪制圖面碟狞,如果非要用族沃,推薦NestedScrollView脆淹。

19盖溺、不要通過Intent在Android基礎(chǔ)組件之間傳遞大數(shù)據(jù)(binder transaction 緩存為1MB)烘嘱,可能導(dǎo)致OOM蝇庭。

20哮内、Application的業(yè)務(wù)初始化加入進(jìn)程判斷,確保只在自己需要的進(jìn)程初始化纹因,特別是后臺進(jìn)程減少不必要的業(yè)務(wù)初始化。

21从绘、新建線程時(shí)僵井,必須通過線程池提供批什,不允許在應(yīng)用中自行閑時(shí)創(chuàng)建線程乳规。

比如:

int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();

int KEEP_ALIVE_TIME = 1;

TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;

BlockingQueue taskQueue = new LinkedBlockingQueue();

ExecutorService executorService = new ThreadPoolExecutor(NUMBER_OF_CORES,NUMBER_OF_CORES*2, KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT, taskQueue,new BackgroundThreadFactory(), new DefaultRejectedExecutionHandler());

//

執(zhí)行任務(wù)

executorService.execute(new Runnnable() {

...

});

22暮的、子線程中不能更新界面冻辩,更新界面必須在主線程中進(jìn)行,網(wǎng)絡(luò)操作不能在主線程中調(diào)用倘感。

23老玛、ThreadPoolExecutor設(shè)置線程存活時(shí)間钧敞,確保空閑時(shí)線程能被釋放余素。

24、謹(jǐn)慎使用Android多進(jìn)程视乐,多進(jìn)程雖然能夠降低主進(jìn)程的內(nèi)存壓力敢茁,但會(huì)有如下問題:

第一佑淀、不能實(shí)現(xiàn)完全退出所有Activity的功能

第二、首次進(jìn)入新啟動(dòng)進(jìn)程頁面會(huì)有延時(shí)的現(xiàn)象(黑屏彰檬、白屏幾秒)

第三伸刃、應(yīng)用內(nèi)多進(jìn)程是,Application實(shí)例化多次逢倍,需要考慮各個(gè)模塊是否都需要在所有進(jìn)程初始化捧颅;

第四、多進(jìn)程間通過SharedPreferencs共享數(shù)據(jù)是不穩(wěn)定

25较雕、SharedPreference提交數(shù)據(jù)時(shí)碉哑,盡量使用Editor的apply(),而非Editor的commit()亮蒋,僅當(dāng)需要確定提交結(jié)果扣典,并據(jù)此有后續(xù)操作是,才用commit()闰蛔。(apply方法提交先寫入內(nèi)存蚤吹,然后異步寫入磁盤二驰,commit方法直接寫入磁盤唬复,頻繁操作的話休建,apply的性能會(huì)優(yōu)于commit);

26、數(shù)據(jù)庫Cursor必須確保使用完后關(guān)閉,以免內(nèi)存泄漏

public void handlePhotos(SQLiteDatabase db, String userId) {

Cursor cursor;

try {

cursor = db.query(TUserPhoto, new String[] { "userId", "content" }, "userId=?", new

String[] { userId }, null, null, null);

while (cursor.moveToNext()) {

// TODO

}

} catch (Exception e) {// TODO

} finally {

if (cursor != null) {

cursor.close();

}

}

}

27男图、多線程操作寫入數(shù)據(jù)庫時(shí),需要使用實(shí)物,避免出現(xiàn)同步問題。

比如:

public void insertUserPhoto(SQLiteDatabase db, String userId, String content) {

ContentValues cv = new ContentValues();

cv.put("userId", userId);

cv.put("content", content);

db.beginTransaction();

try {

db.insert(TUserPhoto, null, cv);

// 其他操作

db.setTransactionSuccessful();} catch (Exception e) {

// TODO

} finally {

db.endTransaction();

}

}

28谍憔、大數(shù)據(jù)寫入數(shù)據(jù)庫時(shí),請使用事務(wù)或其他能夠提高I/O效率的機(jī)制,保證執(zhí)行速度月而。

比如:

public void insertBulk(SQLiteDatabase db, ArrayList users) {db.beginTransaction();

try {

for (int i = 0; i < users.size; i++) {

ContentValues cv = new ContentValues();

cv.put("userId", users[i].userId);

cv.put("content", users[i].content);

db.insert(TUserPhoto, null, cv);

}

//

其他操作db.setTransactionSuccessful();

} catch (Exception e) {

// TODO

} finally {

db.endTransaction();

}

}

29世杀、加載大圖片或者一次性加載多張圖片所刀,應(yīng)在異步線程中進(jìn)行斩披,圖片加載設(shè)計(jì)到IO操作,以及CPU密集操作绑青,容易引起卡頓。

正例:

class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {

...

//

在后臺進(jìn)行圖片解碼

@Override

protected Bitmap doInBackground(Integer... params) {

final Bitmap bitmap = BitmapFactory.decodeFile("some path");

return bitmap;

}

...

}

30庇楞、在 ListView吕晌,ViewPager睛驳,RecyclerView乏沸,GirdView 等組件中使用圖片時(shí)炬转,

應(yīng)做好圖片的緩存荐吵,避免始終持有圖片導(dǎo)致內(nèi)存泄露袒哥,也避免重復(fù)創(chuàng)建圖片,引起

性 能 問 題 哩照。建議使用Fresco购桑、Glide等圖片庫漓帚,可以使用系統(tǒng)LruCache緩存:

正例:

private LruCache mMemoryCache;@Override

protected void onCreate(Bundle savedInstanceState) {

...

//

獲取可用內(nèi)存的最大值叨恨,使用內(nèi)存超出這個(gè)值將拋出 OutOfMemory 異常邪狞。LruCache 通

過構(gòu)造函數(shù)傳入緩存值,以 KB 為單位次伶。

final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);

// 把最大可用內(nèi)存的 1/8 作為緩存空間

final int cacheSize = maxMemory / 8;

mMemoryCache = new LruCache(cacheSize) {

@Override

protected int sizeOf(String key, Bitmap bitmap) {

return bitmap.getByteCount() / 1024;

}

};

...

}

public void addBitmapToMemoryCache(String key, Bitmap bitmap) {

if (getBitmapFromMemCache(key) == null) {

mMemoryCache.put(key, bitmap);

}

}

public Bitmap getBitmapFromMemCache(String key) {

return mMemoryCache.get(key);

}

public void loadBitmap(int resId, ImageView imageView) {

final String imageKey = String.valueOf(resId);

- 45 -

七痴昧、Bitmap、Drawable 與動(dòng)畫

final Bitmap bitmap = getBitmapFromMemCache(imageKey);

if (bitmap != null) {

mImageView.setImageBitmap(bitmap);

} else {

mImageView.setImageResource(R.drawable.image_placeholder);

BitmapWorkerTask task = new BitmapWorkerTask(mImageView);

task.execute(resId);

}

}

class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {

...

// 在后臺進(jìn)行圖片解碼

@Override

protected Bitmap doInBackground(Integer... params) {

final Bitmap bitmap = decodeSampledBitmapFromResource(getResources(),

params[0], 100, 100));

addBitmapToMemoryCache(String.valueOf(params[0]), bitmap);return bitmap;

}

...

}

31冠王、png圖片使用tinypng工具壓縮處理赶撰,減少apk包體積大小

32、在Activity.onPause()或者Activity.onStop()回調(diào)中,關(guān)閉當(dāng)前activity正在執(zhí)行的動(dòng)畫豪娜。

33餐胀、使用ARGB_565代替ARGB_888,在不怎么降低視覺效果的前提下瘤载,減少內(nèi)存占用

34否灾、在有強(qiáng)依賴 onAnimationEnd 回調(diào)的交互時(shí),如動(dòng)畫播放完畢才能操作頁

面鸣奔,onAnimationEnd 可能會(huì)因各種異常沒被回調(diào)墨技,建 議 加 上 超 時(shí) 保 護(hù) 或 通 過 postDelay 替 代

onAnimationEnd。

正例:View v = findViewById(R.id.xxxViewID);

final FadeUpAnimation anim = new FadeUpAnimation(v);anim.setInterpolator(new AccelerateInterpolator());anim.setDuration(1000);

anim.setFillAfter(true);

anim.setAnimationListener(new AnimationListener() {

@Override

public void onAnimationEnd(Animation arg0) {

//判斷一下資源是否被釋放了if (v != null) {

v.clearAnimation();

}

}

});

v.startAnimation(anim);

35挎狸、未完扣汪,待更新~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市锨匆,隨后出現(xiàn)的幾起案子崭别,更是在濱河造成了極大的恐慌,老刑警劉巖统刮,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異账千,居然都是意外死亡侥蒙,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進(jìn)店門匀奏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鞭衩,“玉大人,你說我怎么就攤上這事娃善÷垩埽” “怎么了?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵聚磺,是天一觀的道長坯台。 經(jīng)常有香客問我,道長瘫寝,這世上最難降的妖魔是什么蜒蕾? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮焕阿,結(jié)果婚禮上咪啡,老公的妹妹穿的比我還像新娘。我一直安慰自己暮屡,他們只是感情好撤摸,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般准夷。 火紅的嫁衣襯著肌膚如雪钥飞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天冕象,我揣著相機(jī)與錄音代承,去河邊找鬼。 笑死渐扮,一個(gè)胖子當(dāng)著我的面吹牛论悴,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播墓律,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼膀估,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了耻讽?” 一聲冷哼從身側(cè)響起察纯,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎针肥,沒想到半個(gè)月后饼记,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡慰枕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年具则,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片具帮。...
    茶點(diǎn)故事閱讀 38,747評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡博肋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蜂厅,到底是詐尸還是另有隱情匪凡,我是刑警寧澤,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布掘猿,位于F島的核電站病游,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏稠通。R本人自食惡果不足惜礁遵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望采记。 院中可真熱鬧佣耐,春花似錦、人聲如沸唧龄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至讽挟,卻和暖如春懒叛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背耽梅。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工薛窥, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人眼姐。 一個(gè)月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓诅迷,卻偏偏與公主長得像,于是被迫代替她去往敵國和親众旗。 傳聞我的和親對象是個(gè)殘疾皇子罢杉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,658評論 2 350

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