上一期分享了android內存優化的一些總結,這一期說說我認爲的好的編碼習慣,而後下一期會作安卓數據庫優化的一些總結,逐漸的會將一些性能優化點總結分享出來,確定是不夠全面的但願不足的地方歡迎指出。android
良好的編碼習慣除開編碼規範這個不說外,還有不少影響內存,流暢度,耗電量的地方都是須要注意的。我會隨時補充進來我遇到的相關的好的編碼習慣,但不太容易作到一下就全面。面試
1.1 已知數量時,對相應的數據結構賦值相應的大小數據庫
new ArrayList(5);數組
1.2 勿在循環調用的地方new對象緩存
好比在adapter中的getView去new OnClickListener,View的onDraw方法new Paint,這些循環屢次調用的地方會致使多個對象的產生,不進形成內存增長也會浪費時間。性能優化
1.3 匿名內部類的使用網絡
上一篇博文提到了緣由,匿名內部類會持有外部引用,因此這裏改爲靜態內部類的,同時使用弱引用的方式。數據結構
1.4 enum的使用app
2.1 用變量替代計算ide
不管是for循環中,仍是本身實現一些代碼經過用一個變量記錄值,比循環計算得出來的值更加節省時間。好比
for(int i =0;i < array.length;i++) 能夠替換成
final int size = array.length;
for(int i = 0; i< size;i++),這樣能夠減小循環過程當中的計算
不過聽說如今foreach的方式是最快的,有興趣的朋友能夠測試下。
2.2 字符串的拼接使用StringBuilder或者StringBuffer
好比"select * from " + Tables.table_name+" where id = "+sid+" limit 1";字符串的拼接不光是時間損耗,內存也會損耗。若是一個字符串後面跟着一個+號,再後面是任何的類型表達式:
string_exp + any_exp
Java編譯器會把它變成:
new StringBuilder().append( string_exp ).append( any_exp ).toString()
若是表達式裏有多個+號的話,後面相應也會多多幾個StringBuilder.append的調用,最後纔是toString方法。
而StringBuilder(String)這個構造方法會分配一塊16個字符的內存緩衝區。所以,若是後面拼接的字符不超過16的話,StringBuilder不須要再從新分配內存,不過若是超過16個字符的話StringBuilder會擴充本身的緩衝區。最後調用toString方法的時候,會拷貝StringBuilder裏面的緩衝區,新生成一個String對象返回。
關於字符串拼接的優化除了StringBuilder或者buffer外還能夠作的更好一點,這也是一次面試獲得的經驗,能夠下一次分享給你們。
2.3 注意強制類型轉換
使用Integer.parseInt()而不是(int)Integer.valueOf()而後去作對比,減小類型強制轉換的時間
2.4 對常量使用Static Final修飾符,
2.5 避免內部getters和setters(有爭議)
性能上直接訪問變量更加有效率,可是軟件工程上就對外暴露了同時也不容易面向擴展了,因此這裏只是提出來,並不必定要遵照。
2.6 在私有內部類中,考慮用包訪問權限替代私有訪問權限
訪問外部內的私有方法,會讓虛擬機生成黏合方法,也就是getters和setters的方法從而下降了讀取的性能。
2.7 線程的優先級設定
首先不要同時使用過多的線程,一來難以管理,二來也會耗費cpu資源,致使影響UI線程,因此在使用線程時,在執行優先級不高的狀況下,指定線程最低優先級或者後臺優先級等,保證UI線程的優先級,好比:
new Thread(new Runnable() {
@Override
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_LOWEST);
}
}).start();
2.8 使用System.arraycopy ()代替經過來循環複製數組
2.9 避免循環內部有過多依賴和跳轉,使cpu能流水起來
好比:
for(int i =0; i < N; i++){
if(i <100)
a[i] +=5;
else if(i <200)
a[i] +=10;
else
a[i] +=20;
}
改爲三個循環
for(int i = 0; i < 100; i++)
{
a[i] += 5;
}
for(int i = 100; i < 200; i++)
{
a[i] += 10;
}
for(int i = 200; i < N; i++)
{
a[i] += 20;
}
3.1 set(listener)對於set(null)
3.2 add對應remove
3.3 open對應close
4.1 選擇合適的wakelock模式
PARTIAL_WAKE_LOCK:保持CPU運轉,屏幕和鍵盤燈有多是關閉的。
SCREEN_DIM_WAKE_LOCK:保持CPU運轉,容許保持屏幕顯示但有多是灰的,容許關閉鍵盤燈
SCREEN_BRIGHT_WAKE_LOCK:保持CPU運轉,保持屏幕高亮顯示,容許關閉鍵盤燈
FULL_WAKE_LOCK:保持CPU運轉,保持屏幕高亮顯示,鍵盤燈也保持亮度
ACQUIRE_CAUSES_WAKEUP:不會喚醒設備,強制屏幕立刻高亮顯示,鍵盤燈開啓。有一個例外,若是有notification彈出的話,會喚醒設備。
ON_AFTER_RELEASE:WakeLock被釋放後,維持屏幕亮度一小段時間,減小WakeLock循環時的閃爍狀況
用完必需要記得釋放。
4.2 選擇合適的alarmmanage模式
AlarmManager會維持一個cpu的wakelock。這樣能保證電話休眠時,也能處理alarm的廣播,有4種Alarm類型:
1)RTC_WAKEUP
在指定的時刻(設置Alarm的時候),喚醒設備來觸發Intent。
2)RTC
在一個顯式的時間觸發Intent,但不喚醒設備。
3)ELAPSED_REALTIME
從設備啓動後,若是流逝的時間達到總時間,那麼觸發Intent,但不喚醒設備。流逝的時間包括設備睡眠的任什麼時候間。注意一點的是,時間流逝的計算點是自從它最後一次啓動算起。
4)ELAPSED_REALTIME_WAKEUP
從設備啓動後,達到流逝的總時間後,若是須要將喚醒設備並觸發Intent。
4.3 慎用輪詢
這玩意耗電很大,固然不少時候多是配合上面的AlarmManager使用,能夠在不一樣的界面或者功能,定義不一樣的輪詢時間來作優化等。
5.1 使用緩存區
經過緩存減小磁盤讀取次數
5.2 緩衝塊的IO要比緩衝流IO要快
6.1 合理的synchronized範圍
6.2 合理的try/catch範圍
try/catch住爆出異常的區域,而不是一個大的函數。