图片优化(效果最明显)
-
过度图片的回收
原因分析:
在做冷启动时候,很多人写一个如下
<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 类布局及图片等优化
- 内存泄漏排查优化