Android性能优化总结

时间:2021-04-28 13:37:30

ps:本文是在阅读了《Android开发艺术探索》之后做的总结,感谢!


布局优化
绘制优化
内存泄露优化
响应速度优化
线程优化
View优化


布局优化

首先,选择性能较低的ViewGroup,比如说,LinearLayout和RelativeLayout两个布局,建议选择LinearLayout,因为Relativelayout的功能比较复杂,它的布局过程需要花费更多的CPU时间。LienarLayout和FrameLayout都是一种简单高效的ViewGroup。
include 标签
作用:include 标签可以将一个指定的布局文件加载到当前的布局文件中。

<include
android:id="@+id/my_image"
layout="@layout/image"
android:layout_width="match_parent"
android:layout_height="100dp"
/>
/**比如上述,就是导入了一个image的布局,这里,include 可以几个属性,其中layout:"表
示引入那个布局",其还可以用android:layout_开头的属性,比如,你引入的布局高200dp,
但是这样设置的是100dp那么就只会展示100dp大小的内容,如果没有的话,就会展示200dp,
这里的id属性,如果被包含布局中也有id,那么以include的为准。这种方法效率高的一个很重
要原因是这个布局文件中内容不会一直重复的加载了*/

merge 标签
一般是和include标签一起使用从而减少布局的层级。
在这里推荐使用View Hierarchy查看一个界面上的view层次。

通过AndroidStudio中的Tools--android--Android Device Monitor便可以打开了,既可以去看层级结构。

比如你发现了,当前布局是一个竖直方向的LinearLayout,但是被包含的布局文件也是竖直方向的LinearLayout,那么就会发现被包含的是多余的,可以用merge标签替代。
通俗点讲就是,你在使用include 标签时候,如果发现了你include的布局,与包含它的布局样式是一样的,那么include布局的根可以用merge代替,这样会去掉多余的那层LinearLayout,
经过是实验证明,如果外界是竖直方向的LinearLayout,但include是merge,那么展示的include布局就是竖直方向的,如果include是水平方向的,但不实用merge了,那么展示的就是水平的。


ViewStub
这是一个View,它非常轻量级并且宽高为0,因此他本身不参与任何的布局和绘制过程,
但是它的作用是可以按需加载所需的布局文件,注意,不是加载view。可以叫做懒加载。

 <ViewStub
android:id="@+id/viewstubs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inflatedId="@+id/aaaa"
android:layout="@layout/image"
/>
/**
其中的layout引入一个布局,但是并不会展示在界面上。
一些android:layout_marin*的属性,如果需要应该加载ViewStub上,而不是加载引入的那个
layout中。
给ViewStub设置OnClickListener监听没有效果,设置OnInflateListener()方法也没有反
应,暂时我是没有发现,
ViewStub 设置的宽高,那么子布局就展示多大部分的内容,但是一个特殊的情况,那就是
ViewStep使用了wrap_content,但是内部的layout中的高度用的是match_parent,那么就会
出现展示很小的界面,并且会全部展示(但是是压缩展示),就是必须告诉一个特定的值才可
以,ViewStub有值(以他的为准),如果ViewStub选择100dp,但是布局是300dp,那么就会展
示100dp内容区域的内容。
*/

关键是如何让ViewStub中的layout加载出来,可以通过:

private ViewStub img;
img = (ViewStub) findViewById(R.id.viewstubs);
img.setVisibility(View.VISIBLE);//里面的内容就会出来
img.setVisibility(View.GONE);//里面的内容就会消失

由于不能给ViewStub设置监听,因此一般是通过别的view来控制其显示的。
还有,ViewStub包含的layout,里面的内容是可添加监听的,
只需找到相对应的id 就可以。
你在布局时候,在两个TextView之间加上ViewStub,你什么也看不见,不影响布局,当
ViewStub里面内容展示时候,还是在两个TextView之间,下面的TextView向下留出展示 ViewStub的空间


绘制优化

View
在View的onDraw()方法中,不要创建对象,因为可能会频繁的调用,这样一瞬间就会有大量的对象了,会占有很多的内存和系统gc被频繁的调用。降低了程序的效率。
另外最好不要执行耗时操作,不能执行成千上万的循环操作,这样回强占cpu时间,Google官方定义的性能优化典范中,View的绘制帧率保证60ms最佳,这要求每帧时间不超过16ms

还有比如说ListView的优化、Bitmap的优化之类,都很关键。


内存泄露优化

一般来讲内存泄漏,有两个方面:
(1)静态变量导致的内存泄露
(2)单例模式导致的内存泄漏
(3)属性动画导致的内存泄漏
就拿属性动画来讲,它会持有View,但是View会持有Activity,如果动画没有调用animator.cancel()来停止动画,就一直存在那么activity就会泄露,
所谓的内存泄漏,最主要是activity不能及时的被回收。


响应速度优化

这个的核心就是,避免在主线程中做耗时操作,响应速度体现在Activity启动速度上面,如果在主线程中做了太多事情,会导致Activity启动时候出现黑屏之类的现象
Android规定,Activity如果5秒之内无法响应屏幕触摸事件或者键盘输入事件就会导致ANR(Application not Responding),
ANR,其实进程会在/data/anr目录下面建立traces.txt,文件,可以通过adb pull /data/anr/traces.txt 进行查看。
adb ,存在于你的sdk 里面platform-tools 中,是带有的一个程序,可以通说cmd 启动。


线程优化

最好采用线程池,避免程序中存在大量的Thread,线程池可以重用内部线程,避免了县城创建和销毁所带来的性能开销。