第10章 Android 性能优化
10.1布局优化
人眼所感觉的流畅画面,需要画面的帧数达到40帧每秒到60帧美妙。
在Android中,系统通过VSYNC信号触发对UI的渲染、重绘,其间隔时间。
其间隔事件是16ms。这个16ms起始就是1000ms中显示60帧画面的单位时间,即1000/60。
开发者选项,选择“Profile GPU Rendering”。并选中“on screen bars”选项。这时在屏幕上将显示一些条形图。
每一条柱线都包含三部分。蓝色代表测量绘制Display List的时间。红色代表OpenGl渲染DisplayList所需要的事件,黄色代表CPU等待GPU的事件,中间的绿色横线代表VSYNC时间16ms。
需要控制所有条形图都尽量在绿线下。
10.1.2 避免overdraw
开发者选项,Enable Gpu overDraw。尽量优化绘图层次,尽量增大蓝色的区域,减少红色区域。
10.1.3 优化布局层级
通过扁平的Relativelayout来降低通过LinearLayout嵌套所产生布局树的高度,从而提高UI渲染的效率。
10.1.4.1 使用标签重用Layout
如果需要在标签中覆盖类似原布局中android:layout_XXXX的属性,就必须在标签中同时指定android:layout_width和android:layout_height属性。
10.1.4.2 使用实现View的延迟加载
是一个非常轻量级的组件,它不仅不可视,而且大小为0。
如何加载ViewStub
1、通过普通的findViewById方法找到组件。
2、接下来有两种方式。重新显示这个View。
(1)view.setVisibility(View.Visible)
(2)View inflateView =mViewStub.inflate()。
两种方式区别在于。inflate()方法可以返回引用的布局,从而可以通过View.findViewById()方法来找到对应的控件。
一旦ViewStub被设置为可见或是被inflate了,就不存在了。取而代之的是被inflate的Layout,并将这个Layout的Id重新设置为《ViewStub》中通过android:inflatedId属性所指定的ID。
10.2 内存优化
10.2.1 什么是内存
我们通常说的内存是手机的RAM,它包括以下几个部分
1、寄存器。速度最快的存储场所,位于处理器内部。在程序中无法控制。
2、栈(Stack)。存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中。
3、堆。堆内存用来存放new创建的对象和数组。在堆中分配的内存,由java虚拟机的自动垃圾回收器来管理。
4、静态存储区域。
静态存储区域是指在固定的位置存放应用程序运行时一直存在的数据,java在内存中专门划分了一个静态区域来管理一些特殊的数据变量如静态的数据变量。
5、常量池
JVM虚拟机必须为每个被装载的类型维护一个常量池。常量池就是该类型所用到常量的一个有序集合。包括直接常量和对其他类型、字段和方法的符号引用。
1、当定义一个变量,jva虚拟机就会在栈中为该变量分配内存控件,当该变量作用域结束后,这部分内存控件马上被用作新的空间进行分配。
2、当使用new方式去创建一个变量,那么就会在堆中为这个对象分配内存空间,即使该对象的作用域结束,这部分内存也不会立即被回收,而是等待系统GC进行回收。
10.2.4.1 Bitmap优化
1、使用适当分辨率和大小的图片
在图片列表界面,可以使用图片的缩略图。
2、即使回收内存。
3、使用图片缓存
通过内存缓存和硬盘缓存
10.2.4.2 代码优化
1、对常量使用static 修饰符
2、使用静态方法,静态方法比普通方法提高15%左右的访问速度。
3、减少不必要的成员变量。
4、减少不必要的对象
5、尽量不要使用枚举、少用迭代器。
6、对Cursor、Receiver、Sensor,File等对象。要注意对它们的创建、回收与注册。
7、避免使用IOC框架,IOC通常使用注解,反射来实现。
8、使用RenderScript、OpenGl来进行复杂的绘图操作。
9、使用SurfaceView来替代View进行大量、频繁的绘图操作。
10、尽量使用视图缓存,而不是每次都执行inflate()方法解析视图。
第12章 Android 5.X新特性详解
12.1.1 材料的形态模拟
材料的形态模拟是Material Design中最核心 也是改变最大的一个设计。
12.6 列表与卡片
在Android 5.x中RecyclView。RecyclView是support_v7包中的新组件,是一个强大的滑动组件,与经典的listview相比,它同样具有item回收复用的功能,但是recycleView可以直接把ViewHolder实现封装起来,用户只要实现自己的ViewHolder就可以了,该组件会自动回收复用每一个item。
12.6.2CardView
CardView首先需要在项目中引入com.android.support:cardview-v7:21+的依赖。其次在布局文件中使用CardView的时候需要引入一个新的名字空间。
12.7Activity 动画
Android 5.X 提供了三种Transition类型
1、进入:一个进入的过度动画决定Activity中的所有的视图怎么进入屏幕。
2、退出:一个退出的过度动画决定activitu中的所有的试图怎么退出屏幕。
3、共享元素:一个共享元素过度动画决定两个Activities之间的过度,怎么共享它们的视图。
其中,进入和退出效果包括:
explode(分解)——从屏幕中间进或出,移动视图
slide(滑动) ——从屏幕边缘进或出,移动视图
fade(淡出) ——通过改变屏幕上视图的不透明度达到添加或者移除视图
共享元素
changeBounds——改变目标视图的布局边界
changeClipBounds——裁剪目标视图边界
changeTransform——改变目标视图的缩放比例和旋转角度
changeImageTransform——改变目标图片的大小和缩放比例。
12.8.1 Ripple效果
点击后的波纹效果。
波纹有边界是指波纹被限制在控件的边界中。波纹超过边界则波纹不会限制在控件边界中,会呈圆形发散出去。
12.8.2 Circular Reveal
一个View以圆形的形式展开、揭示出来。
12.8.3 View state changes Animation
StateListAnimator
拼图算法
N Puzzle问题。随机交换图片的位置之后,生成的拼图游戏很多都是无解的,经测试,这个比例高达50%,所以必须先判断生成的拼图是否有解。
我们将图片暂时用数字来代替,这样整个拼图游戏就变成了一个数字矩阵,假设随机得到了这个矩阵,其中X用来代表空格的照片。
对于图片拼图的还原,与还原图13.4中13.4的数字矩阵,现在,将这个举证携程一维数组的形式,并将其记为序列A。
A={12,1,10,2,7,11,4,14,5,x,9,15,8,13,6,3}
再定义一个“倒置变量值”的算法——T。T i表示序列A中位于第i位之后,比Ai小的元素的个数(不算X)。例如,对上面的序列A中的每个元素“倒置变量值”的计算,其结果如下所示。
11,0,8,0,4,6,1,6,1,3,4,2,2,1
最后,求得所有变量值的和Sumr=49。在Npuzzle算法中,使用如下两个原则来判断一个N puzzle问题是否有解
1、如果序列A的宽度为奇数,那么每个可解的问题所定义的“倒置变量值”的和——Sumr必须是偶数。
2、如果序列A的宽度为偶数,那么当空格X位于从下往上数的奇数行中时,定义的倒置变量值的和——Sumr必须是偶数;当空格X位于从下往上数的偶数行中时,定义的“倒置变量值”的和——Sumr必须是奇数。
2048 游戏分析
自我练习源代码