圖片優化(效果最明顯)
-
過度圖片的回收
原因分析:
在做冷啓動時候,很多人寫一個如下
<style name="MainTheme" parent="@android:style/Theme.Wallpaper.NoTitleBar">
<item name="android:windowNoTitle">true</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@mipmap/ic_bg</item>
</style>
這裏使用 android:windowBackground 設置了一個全局的背景圖片,如果不回收,會一直暫用很大的內存
我們可以使用 dumpsys meminfo 包名 | grep TOTAL: 查看該應用使用android:windowBackground的大小
t7-p1-s201-aw18:/ # dumpsys meminfo 包名|grep TOTAL:
^[[A TOTAL: 27921 TOTAL SWAP PSS: 0
我們在看一下沒有使用了android:windowBackground應用佔用的內存
t7-p1-s201-aw18:/ # dumpsys meminfo 包名|grep TOTAL:
TOTAL: 22924 TOTAL SWAP PSS: 0
我們可以看一下,相差了將近5M的內存差,如果不回收,這5M是一直都存在的
其實這圖片在PC上面圖片只有624KB,爲啥會佔用這麼大的內存,有興趣的可以參考【android學習】APP圖片內存計算
優化方式:
在onCreate方法裏面,將window的windowBackground設置爲null,這樣就可以等待系統回收
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.aa_activity_main);
getWindow().setBackgroundDrawable(null);
}
因爲每次run之後,內存大小會有所改變,但是大體的還是可以看出來,再來對比一下
t7-p1-s201-aw18:/ # dumpsys meminfo 包名|grep TOTAL:
TOTAL: 23365 TOTAL SWAP PSS: 0
-
資源目錄結構調整
原因分析:
圖片資源一般會存放在mipmap-hdpi,mipmap-mdpi,mipmap-xhdpi,mipmap-xxhdpi,mipmap-xxxhdpi這些目錄裏面,有些爲了適配不同手機機型,會將不同尺寸的圖片放在相應的目錄裏面
drawable文件尺寸與pc中文件尺寸關係
目錄 | 屏幕密度 |
---|---|
mipmap-ldpi | 120dpi |
mipmap-mdpi | 160dpi |
mipmap-hdpi | 240dpi |
mipmap-xhdpi | 320dpi |
mipmap-xxhdpi | 480dpi |
按照不同的適配機型的屏幕密度,分別讀取不同文件目錄
可以通過如下指令查看你的車機的屏幕密度:
C:\Users\Administrator>adb shell wm density
Physical density: 240
因爲我的車機屏幕密度是240,所以我將背景圖片放在了mipmap-hdpi,同時設置佈局文件的背景android:background="@mipmap/ic_bg"
我們看一下內存:
t7-p1-s201-aw18:/ # dumpsys meminfo 包名|grep TOTAL:
TOTAL: 16348 TOTAL SWAP PSS: 0
然後我們將同一張圖片移動到mipmap-xxxhdpi,看一下內存:
t7-p1-s201-aw18:/ # dumpsys meminfo 包名|grep TOTAL:
TOTAL: 12464 TOTAL SWAP PSS: 0
可以看到同一張圖片,存放不同目錄,佔用的內存不一樣
優化方式:
在圖片不失真的前提下,將大圖移動到高分辨率的目錄裏面,會降低圖片佔用內存
-
圖片顯示優化
原因分析:
我們使用一個ImageView
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@mipmap/ic_bg"
android:visibility="gone"/>
分別將該ImageView設置爲android:visibility="visible",佔用內存如下
t7-p1-s201-aw18:/ # dumpsys meminfo 包名|grep TOTAL:
TOTAL: 16626 TOTAL SWAP PSS: 0
將該ImageView設置爲android:visibility="gone",佔用內存如下
t7-p1-s201-aw18:/ # dumpsys meminfo com.iflytek.autofly.meminfotest|grep TOTAL:
TOTAL: 16586 TOTAL SWAP PSS: 0
可以看到設置爲gone依然會佔用內存
優化方式:
一些沒有使用的佈局,直接刪除,不要設置爲gone
-
自定義背景drawable代替圖片背景圖
這個很好理解,
- 比如一張純色的圖片,你完全可以使用shape來實現。
- 一些複雜的圖片,如果能用SVG實現,就使用SVG
-
幀動畫圖片清理及相關幀率優化
在做播放動畫效果時候,一般會使用幀動畫
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
<item
android:drawable="@mipmap/ic_music_playing_anim1"
android:duration="200" />
<item
android:drawable="@mipmap/ic_music_playing_anim2"
android:duration="200" />
<item
android:drawable="@mipmap/ic_music_playing_anim3"
android:duration="200" />
</animation-list>
因爲動畫會將所有圖片加入到內存,所以在不影響動畫效果的條件下,可以刪掉部分動畫圖片,達到減少內存目的
-
圖片縮放
不同的圖片格式佔用的內存大小不同:
- ALPHA_8:每個像素佔用1byte內存
- ARGB_4444:每個像素佔用2byte內存
- ARGB_8888:每個像素佔用4byte內存 (默認)
- RGB_565:每個像素佔用2byte內存
在加載圖片時候,顏色模式爲ARGB_8888,在不影響圖片效果前提下,可以將圖片做一定壓縮,轉換圖片格式
public static Bitmap decodeBitmap(Contextcontext, intresId) {
BitmapFactory.Optionsopt = newBitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;
InputStreamis = context.getResources().openRawResource(resId);
returnBitmapFactory.decodeStream(is, null, opt);
}
資源優化(效果明顯)
-
無用資源清理:jar包,Library包
當項目達到一定規模以後,就會存在一些沒有使用的jar包,可以刪除達到減少內存佔用
-
so文件的刪除
手機爲了適配不同手機機型,會存放很多版本的so文件,手機可以根據不同手機,分渠道打包,因爲我做的事車機,所以,就直接幹掉沒有使用的類型了
- armeabi
- armeabi-v7a
- arm64-v8a
- x86
- x86_64
- mips
- mips64
-
刪掉沒有使用的佈局文件
可以使用lint工具,具體參考:Android 性能優化:使用 Lint 優化代碼、去除多餘資源
代碼優化(見效很慢,是一個漫長的過程)
這裏不具體描述:
- 清除不必要的對象應用
- 避免循環中創建大量對象導致內存抖動
- listview recycleview 類佈局及圖片等優化
- 內存泄漏排查優化