第十五章Android性能优化(Android开发艺术探索)

15.1.1布局优化

1.布局优化的思想:减少布局文件的层级(层级少了,绘制时的工作量就少了)

方法一:减少布局文件的层级

优化步骤:
1.1.删除布局中无用的控件和层级
1.2.选择简单高效的viewGroup 排行榜:FramLayout/LinearLayout>RealativeLayout(原因:RealativeLayout功能复杂,布局过程需要更多的cpu时间)
1.3.但有的时候FramLayout和LinearLayout想要完成产品需求需要嵌套很多次,这个时候就推荐使用一个RealativeLayout搞定
(也就是说布局简单的时候使用FramLayout/LinearLayout,复杂的时候需要嵌套多个FramLayout/LinearLayout的时候使用RealativeLayout)

方法二:标签优化采用

<include>    :布局重用 <include layout="@layout/abc.xml">
<merge>      :一般和<include>配合使用,减少布局的层级
<ViewStub>:按需加载(就是加了<ViewStub>标签后,系统会在需要<ViewStub>下的布局的时候,才加载到内存)

标签优化注意事项:

<include> :<include> 标签内只支持 androd:layout_开头的属性,比如android:background就不支持;
android:id是个特例,如果<include android:id@+id/new_bg> (include标签中包含了id),被包含的根元素也包含了布局,那么以<include android:id@+id/new_bg> 指定的id为准
<merge> :如果两个vertical LinearLayout嵌套,那么就有一个是多余的,那么可以使用<merge> 代替<LinearLayout>,一般和<include>标签结合使用,去掉被包含的布局的根布局。
<ViewStub> : 继承了view,宽高都是0,按需加载(例如:没有网络,那么布局就没必要展示,只展示一个错误页就好)
使用方法:
<ViewStub
android:id="@+id/stub_import"//自己的di
android:InFlatedId="@+id/panel_import"//根布局id
android:width="wrap_content"
android:height="wrap_content"
/>
加载:
((ViewStub)findViewById(R.id.stub_import)).setVisibility(View.Visible);
或者
((ViewStub)findViewById(R.id.stub_import)).inflate();

这两个方法的作用都是1.去掉ViewStub2.还原布局(因为ViewStub的布局高宽为0,所以要去掉)

验证:需要寻找一个能够查看布局性能的工具,分别使用上述方法和普通实现方法,测试是否真的优化了布局,节省了cpu

15.1.2绘制优化

原理:避免的onDraw方法中执行大量操作
1.在onDraw中不要new(不要创建新的局部对象);(原因:onDraw调用频繁,每调用一次就new一次到堆内存中,
结果就是:1.占内存2.频繁gc(降低了程序的执行效率))解决方案:实在要new在onDraw方法外面new,实现单例。
2.在onDraw中不要做耗时和循环操作
(扩展:google优化标准:view绘制帧率<60fps,即:每帧的绘制时间<=16ms(16ms = 1000/60))

15.1.3内存泄露优化

优化方案:
1.避免写出内存泄露的代码
2.通过分析工具(比如MAT)找出潜在的内存泄露
场景:
1.静态变量导致
1.1赋值给静态变量
static Context context = this;
1.2被静态变量引用
static View v = new View(this);
结果:activity无法正常销毁
2.单例模式导致
单例模式的生命周期和application保持一致,(因为得到单例也是static,程序不退出static永远在堆内存中)
如果在Test.getInstance().registerListener(this) 那么如果没有调用解注册的方法(remove(Listener)),那么activity就会一直被单例持有,得不到释放。
3.属性动画导致
属性动画有一种无限循环的动画,如果在onDesdroy没有去停止动画,
结果:这个时候activity的view会被动画持有;view又 持有了activity,导致activity无法释放
解决方案:在desdroy 中animator.cancel();

15.1.4响应速度优化和ANR日志分析

响应速度优化的核心思想:避免在主线程中做耗时操作
解决方案:耗时放在线程中执行(即异步执行)
ANR的原因:
1.5秒无响应
(即:5秒内无法响应屏幕触摸事件;5秒内无法响应键盘输入事件)
2.BroacastReceiver10秒内还未执行完操作
定位ANR的问题:
ANR发生后,系统会在程序的“程序包名/data/anr”创建一个文件traces.txt。分析这个文件可以定位到原因

15.1.5listview和bitmap优化

listview方案(三个方面):
1.采用viewHolder重用
2.避免在getView中执行耗时操作
3.根据列表的滑动状态来控制任务的执行频率(例如:快速滑动,不适合开始大量异步任务,可以尝试开启硬件加速使listview更流畅。)
bitMap方案:
通过BitmapFactory.options对图片采样,通过inSampleSize参数控制图片的高和宽

15.1.6线程优化

方案:
采用线程池
线程池的好处:
1.可以重用内部线程,避免线程的创建和销毁带来的性能开销
2.线程池可以控制线程池的最大并发数,避免大量的线程抢占系统资源造成阻塞
使用:
采用线程池,不要每次都new Tread对象

15.1.7性能优化建议

1.避免创建过多的对象
2.不要过多的使用枚举,枚举占用的内存空间要比整型大
3.常量请使用static final来修饰
4.使用一些Android特有的数据结构,比如SparseArray 和 Pair ,他们都具有更好的性能
5.适当使用软引用和弱引用
6.采用内存缓存和磁盘缓存
7.尽量采用静态内部类,这样可以避免潜在的由于内部类而导致的内存泄露

15.2内存泄露分析与MAT工具

15.3提高程序的可维护性

1、命名要规范
2、代码的排版
3、只为非常关键的代码加注释

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值