页面的优化
include布局:
当页面内容比较多,而且此页面重复性比较大的时候,我们通过include将子布局引 入到一个布局文件中。
原理:
在解析sml布局的时候,如果检测到include标签,则把布局下的根视图添加到父布局所在的xml中。
在解析xml标签的时候,我们会用到parseInclude函数去解析include标签。
Merge标签
当子布局的根视图和他的父视图是同一类型
在这种情况,我们通过merge就可以合并UI布局,降低UI嵌套层次。作为merge子视图的顶级视图会来解决掉多余的层次。
ViewStub视图
是一个不可见的和能在运行期间延迟加载的视图、宽高都为0的view。
使用情况:
在GridView在加载网络请求的数据时,需要通过网络返回来判断是否加载GridView,这时候就需要用到ViewStub来进行延迟加载。
原理:
用ViewStub包裹的布局,在默认的情况下不会加载,只是用来占位。只有调用它的inflate或者setVisibility才会加载相应的布局。
Android UI布局过程需要遵守的原则
尽量多使用RelativeLayout,不要使用绝对布局
在ListView等列表组件中尽量避免使用LinearLayout的layout_weight属性
将可复用的组件抽取出来并通过<include/>标签使用
使用<ViewStub/>标签来加载一些不寻常的布局
使用<merge/>标签减少布局的嵌套层次
内存优化
珍惜Services资源
当启动一个Service,系统会倾向为了保留这个Service而一直保留Service所在的进程。这减少了系统能够存放到LRU缓存中的进程数量,他会影响App之间的切换效率。这甚至会导致系统内存使用不稳定,从而无法继续保持住所有目前正在运行的Service。
为了免除这个限制,最好使用IntentService,他会在处理完自己的intent任务之后尽快结束自己。
避免bitmaps的浪费
在加载bitmap时,仅仅需要保留适配当前屏幕分辨率的数据即可。高于分辨率的图片需要做缩略,所以,建议使用成熟的ImageLoader框架,如Glide、Picaso、Fresco等。
使用优化的数据容器
利用Android FrameWork里面优化过的容器类。相对于使用java的HashMap,我们使用SpareArray会比较节省内存消耗,因为HashMap中需要额外创建一个实例对象来记录Mapping操作。
注意代码抽象
虽然抽象能够替身代码的灵活性和可维护性,但是也导致一个显著的开销:用于执行的等量代码会被map到内存中。所以,如果抽象没有有效替身效率,应该尽量避免。
避免使用外来注入框架
因为一些注入框架会扫描代码并执行许多初始化操作,而这些代码需要大量的RAM来map代码。同时会长时间保留在RAM中。
使用ProGuard来剔除不要的代码
ProGuard能够通过移除不需要的代码,重命名、域与方法等方面或对代码进行压缩,优化与混淆。使用ProGuard能够更少mapped代码所需的RAM。
使用多进程
通过将App组件切分为多个组件,运行在不同进程中。例如音乐播放,将播放和前台的UI操作分开。
内存泄漏
使用Android Device Moniter中的DDMS中的heap进行内存泄漏分析。
使用square开发的叫做LeakCanary的库进行分析。他会自动追踪内存泄漏问题。
性能优化
过度绘制
通过Android自带工具进行检查
Android图形渲染
通过Hierarchy Viewer去检查测量的时间、布局的时间、绘制的时间。
数据采集和分析工具
TraceView是Android平台特有的数据采集和分析工具。主要用于分析某个线程中各个函数的调用情况,包括cpu使用时间、调用次数、函数真实执行时间等信息。