一.布局优化
核心思想:就是布局层级的扁平化,尽量减少布局层级。
1.布局使用
RelativeLayout:会让子View执行2次onMeasure()。 为什么会被测量两次,答案:竖直和水平各一次。
LinearLayout:只有在使用weight的时候才会让子View执行2次onMeasure()。
在不影响布局深度的情况下尽量使用LInearLayout。
如果使用FrameLayout,LinearLayout无法实现产品效果,需要嵌套那么可以使用RelativeLayout布局。
Tips:如果嵌套时使用了RelativeLayout,那么一定要注意RelativeLayout嵌套RelativeLayout这种情况。耗时成倍增长。
2.使用标签
2.1<include>标签
主要用于布局重用。可以将一个布局添加到当前的布局文件中。
<include>标签支持android:layout_xx属性的设置,也包含android:id_xx设置。
如果<include>标签指定了android:layout_xx这种属性,那么要求android:layout_width和android:layout_heiht一定要存在,否则 android:layout_xx属性无法生效。
2.2<merge>标签
主要用于去除不必要的布局层级,<merge>使用的最理想情况就是你的根布局是FrameLayout,同时没有使用Background属性。但其它布局也是可以的。
Tips:
1.<merge>标签只可以作为xml layout的根节点。
2.当需要扩充的xml layout本身是由merge作为根节点的话,需要将被导入的xml layout置于viewGroup中,同时需要设置attachToRoot为True。
2.3<ViewStub>标签
主要用于延迟加载布局文件也就是按需加载。它继承与View且宽高都是0,不可见。
有许多页面在开始的时候不需要显示当然也就不需要加载。这时候就可以使用<ViewStub>标签。
示例代码:
<ViewStub
android
:id=
"@+id/myViewStub"
android
:inflatedId=
"@+id/myInflatedViewId"
android
:layout=
"@layout/include_demo"
android
:layout_width=
"wrap_content"
android
:layout_height=
"wrap_content"
android
:layout_below=
"@id/clickMe"
/>
myViewStub是ViewStub的ID。
myInflatedViewId是需要延迟加载布局文件的根布局ID。
include_demo是需要延迟加载的布局文件。
在代码中使用:
第一种: ViewStub myViewStub = (ViewStub)findViewById(R.id.myViewStub);
if (myViewStub != null) {
myViewStub.inflate();
第二种:
myViewStub.setVisibility(View.VISIBLE);
}
Tips:
1.一旦布局文件加载完成之后,ViewStub就会从当前布局层级中删除。
<ViewStub>标签不支持标签<merge>,如果需要延迟夹的根布局文件根布局是<merge>那么程序就会报错。如果根布局不是<merge>而是其中间接使用则没有问题。
3.绘制
16ms
1.onDraw()方法中不能创建新的局部对象。onDraw()方法会被频繁调用。
2.onDraw()方法中不能执行耗时任务。
二.内存泄漏
1.概念
内存泄漏:当一个对象已经不在被使用本该被回收,但是却被另一个对象持有引用,没法释放,这就导致了本该被GC回收的对象仍然存在对内存中,造成了内存泄漏。
2.影响
OOM的主要原因之一,也是程序变慢的原因之一。
3.常见内存泄漏
1.静态变量导致的内存泄漏。例如静态:Activity,Context
2.静态View
2.单例模式导致的内存泄漏。
3.循环动画导致的内存泄漏。
4.内部类/匿名内部类
5.Handler:非静态Handler类或者延时消息。
6.Thread 直接创建也是内部类形式
7.TimerTask直接创建也是内部类形式
8.监听器,广播,注册服务 在不用时没有进行反注册。
9.集合对象造成的泄漏,如果使用了静态修饰很严重。
10.资源对象没有关闭造成内存泄漏,例如:文件,Cursor等。
4.常用的工具
1.大名鼎鼎的LeakCanary,相信没人会不知道。
Monitors,Mat,LeakCanary等。