一、xml文件布局優(yōu)化
1.使用include 標(biāo)簽
抽取多個(gè)布局文件共用的代碼塊沸停,在需要的位置使用include標(biāo)簽添加進(jìn)去。
減少代碼量,提高代碼維護(hù)性
2.使用merage標(biāo)簽
降低UI布局的嵌套層次浸颓。
使用情景:
a.布局根結(jié)點(diǎn)是FrameLayout且不需要設(shè)置background或padding等屬性,可以用merge代替旺拉,因?yàn)锳ctivity內(nèi)容布局的parent view就是個(gè)FrameLayout(就setContentView)产上,所以可以用merge消除只剩一個(gè)
b.某布局作為子布局被其他布局include時(shí),使用merge當(dāng)作該布局的頂節(jié)點(diǎn)蛾狗,這樣在被引入時(shí)頂結(jié)點(diǎn)會自動被忽略晋涣,而將其子節(jié)點(diǎn)全部合并到主布局中。
3.使用ViewStub標(biāo)簽
Viewstub標(biāo)簽同include標(biāo)簽一樣可以用來引入一個(gè)外部布局沉桌,不同的是谢鹊,viewstub引入的布局默認(rèn)不會擴(kuò)張,即既不會占用顯示也不會占用位置留凭,從而在解析layout時(shí)節(jié)省cpu和內(nèi)存佃扼。 viewstub常用來引入那些默認(rèn)不會顯示,只在特殊情況下顯示的布局
注意:Viewstub控制的是一個(gè)布局文件蔼夜,而非某個(gè)View兼耀。
某些布局屬性要加在ViewStub而不是實(shí)際的布局上面,才會起作用,比如android:layout_margin*系列屬性瘤运,如果加在TextView上面窍霞,則不會起作用,需要放在它的ViewStub上面才會起作用拯坟。而ViewStub的屬性在inflate()后會都傳給相應(yīng)的布局但金。
使用方法:
通過(ViewStub)findViewById(id)找到ViewStub,通過stub.inflate()展開ViewStub郁季,然后得到子View傲绣。
private View errorView;
private void showError() {
// not repeated infalte
if (errorView != null) {
errorView.setVisibility(View.VISIBLE);
return;
}
ViewStub stub = (ViewStub)findViewById(R.id.error_layout);
errorView = stub.inflate();
Button networkSetting = (Button)errorView.findViewById(R.id.network_setting);
Button refresh = (Button)errorView(R.id.network_refresh);
}
private void showContent() {
if (errorView != null) {
errorView.setVisibility(View.GONE);
}
}
/--------------------------------------------/
ViewStub使用,展開方式:
ViewStub stub = (ViewStub)findViewById(R.id.network_error_layout);
networkErrorView = stub.inflate();
或者
View viewStub = findViewById(R.id.network_error_layout);
viewStub.setVisibility(View.VISIBLE); // ViewStub被展開后的布局所替換
networkErrorView = findViewById(R.id.network_error_layout); // 獲取展開后的布局
雖然把View的初始可見View.GONE但是在Inflate布局的時(shí)候View仍然會被Inflate巩踏,也就是說仍然會創(chuàng)建對象秃诵,會被實(shí)例化,會被設(shè)置屬性塞琼。也就是說菠净,會耗費(fèi)內(nèi)存等資源。
ViewStub是一個(gè)輕量級的View彪杉,它一個(gè)看不見的毅往,不占布局位置,占用資源非常小的控件派近∨饰ǎ可以為ViewStub指定一個(gè)布局,在Inflate布局的時(shí)候渴丸,只有ViewStub會被初始化侯嘀,然后當(dāng)ViewStub被設(shè)置為可見的時(shí)候,或是調(diào)用了ViewStub.inflate()的時(shí)候谱轨,ViewStub所向的布局就會被Inflate和實(shí)例化戒幔,然后ViewStub的布局屬性都會傳給它所指向的布局。
4.盡量為所有分辨率創(chuàng)建資源土童,減少不必要的硬件縮放诗茎,這會降低UI的繪制速度
二、性能優(yōu)化
1.數(shù)據(jù)庫優(yōu)化
a.為數(shù)據(jù)建立索引---------------------------------------------------->>>>需要去查資料怎么建立和使用献汗,沒有使用過敢订,在數(shù)據(jù)庫沒有達(dá)到幾萬條數(shù)據(jù)時(shí),效果貌似不是很明顯罢吃,不過是個(gè)很好的習(xí)慣楚午,以后需要注意
b.使用事務(wù)
同一事務(wù)內(nèi)的所有修改要么都完成要么都不做,如果某個(gè)修改失敗刃麸,會自動回滾使得所有修改不生效醒叁。
Sqlite默認(rèn)會為每個(gè)插入司浪、更新操作創(chuàng)建一個(gè)事務(wù)泊业,并且在每次插入把沼、更新后立即提交。
顯示的創(chuàng)建事務(wù)->執(zhí)行100條語句->提交會使得這個(gè)創(chuàng)建事務(wù)和提交這個(gè)過程只做一次吁伺,通過這種一次性事務(wù)可以使得性能大幅提升饮睬。
2.代碼優(yōu)化
a.算法優(yōu)化,邏輯優(yōu)化
b.緩存
緩存主要包括對象緩存篮奄、IO緩存捆愁、網(wǎng)絡(luò)緩存、DB緩存窟却。
對象緩存能減少內(nèi)存的分配昼丑,IO緩存減少磁盤的讀寫次數(shù),網(wǎng)絡(luò)緩存減少網(wǎng)絡(luò)傳輸夸赫,DB緩存較少Database的訪問次數(shù)菩帝。
方式:
文件IO緩存
使用具有緩存策略的輸入流,BufferedInputStream替代InputStream茬腿,BufferedReader替代Reader呼奢,BufferedReader替代BufferedInputStream.對文件、網(wǎng)絡(luò)IO皆適用切平。
網(wǎng)絡(luò)緩存:okhttp設(shè)置握础。
數(shù)據(jù)存儲優(yōu)化
包括數(shù)據(jù)類型、數(shù)據(jù)結(jié)構(gòu)的選擇悴品。
a. 數(shù)據(jù)類型選擇
字符串拼接用StringBuilder代替String禀综,在非并發(fā)情況下用StringBuilder代替StringBuffer。如果你對字符串的長度有大致了解苔严,如100字符左右菇存,可以直接new StringBuilder(128)指定初始大小,減少空間不夠時(shí)的再次分配邦蜜。
64位類型如long double的處理比32位如int慢
使用SoftReference依鸥、WeakReference相對正常的強(qiáng)應(yīng)用來說更有利于系統(tǒng)垃圾回收
final類型存儲在常量區(qū)中讀取效率更高
LocalBroadcastManager代替普通BroadcastReceiver,效率和安全性都更高
SparseArray悼沈、SparseBooleanArray贱迟、SparseIntArray、Pair絮供。
Sparse系列的數(shù)據(jù)結(jié)構(gòu)是為key為int情況的特殊處理衣吠,采用二分查找及簡單的數(shù)組存儲,加上不需要泛型轉(zhuǎn)換的開銷壤靶,相對Map來說性能更優(yōu)缚俏。
異步,利用多線程提高TPS
提前或延遲操作,錯(cuò)開時(shí)間段提高TPS
不在Activity忧换、Service恬惯、BroadcastReceiver的生命周期等對響應(yīng)時(shí)間敏感函數(shù)中執(zhí)行耗時(shí)操作,可適當(dāng)delay亚茬。
Java中延遲操作可使用ScheduledExecutorService酪耳,不推薦使用Timer.schedule;
Android中除了支持ScheduledExecutorService之外,還有一些delay操作刹缝,如
handler.postDelayed碗暗,handler.postAtTime,handler.sendMessageDelayed梢夯,View.postDelayed言疗,AlarmManager定時(shí)等。
對于第一次調(diào)用較耗時(shí)操作颂砸,可統(tǒng)一放到初始化中洲守,將耗時(shí)提前。