Android性能优化
Android性能优化主要分几大类:1。app启动优化 2.布局优化 3. 响应优化 4.内存优化 5.网络优化
一。性能分析工具
1。Hierarchy Viewer提供了一个可视化的界面来检测布局的层级,让我们可以优化布局层级,删除多余的不必要的层级,提升布局速度
其中下边有三个圆形的图标分别表示测量 、 排版、画布局的性能 绿色表示比50%的都快 黄色表示比50%都慢,红色表示是最慢的
2. TraceView 一个图形化的工具,用来展示和分析方法的执行时间。根据展示的时间来进行方法的优化
二。App启动优化
1.application的onCreate方法中不要做太多的事情
2.首屏activity尽量要简化
三。布局优化
1.尽量减少布局层级和复杂度
去除不必要的父布局
尽量不要嵌套使用RelativeLayout
多用TextView的Drawable
如果HierarchyViewer的层级超过了五层一定要优化
2.使用include来重用布局
3.listview的优化
convertView的复用
引入ViewHolder来减少findViewById();
数据要使用分页加载
四。响应优化
Anr产生时,会在data\anr\traces.txt 生成一个日志文件,可以查看导致anr产生的原因
如何避免:不要在ui线程执行耗时的操作,包括网络请求 数据解析 图片加载,耗时的操作要放在子线程中执行
五。内存优化
主要出现的问题:内存消耗过大,内存泄露,内存抖动最主要的原因是因为gc操作过于频繁,在进行gc的时候所在线程会停止运行
内存消耗过大:Android中常见的就是图片资源消耗过大,因此在加载图片的时候建议使用开发的图片框架,比如universal-image-loader,或者是glide
内存泄露: 1.对context的引用 如果是全部变量引用context这时候该activity的生命周期被延长,这时候可以用application的context。
使当前的activity可以及时的销毁掉,释放内存
总结:根据组件的生命周期合理使用context
2.内部类的问题
当在一个类中new一个内部类的时候,这时内部类会持有外部类的引用,这时候建议使用静态内部类,这样当内部类创建的时候并不需要外部类的引用,
减少外部类的生命周期,使其可以更好的被回收释放资源
如果内部类想调用外部类的方法,可以使用弱引用
代码示例:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_memory_leak);
new DemoHandler(this).sendEmptyMessageDelayed(1, 60 * 1000);
}
private static class DemoHandler extends Handler {
private final WeakReference<HandlerLeakActivity> mActivity;
private DemoHandler(HandlerLeakActivity activity) {
this.mActivity = new WeakReference<>(activity);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
HandlerLeakActivity activity = mActivity.get();
if (activity != null) {
activity.doSomething();
}
}
}
private void doSomething() {
}
3.观察者 listener 广播等注册和销毁没有成对出现,会出现内存泄露
常用的方法有 add\remove register\unregister bind\unbind
4.资源泄露
常见的有:cursor、io、数据库链接等没有及时的关闭
5.bitmap内存泄露
bitmap没有及时回收导致内存泄露
一般情况下可以使用软引用,当内存不够的时候可以回收掉
6.在UI看不见时释放Memory
在用户切换到其他的app,并且你的app页面不可见时,你应该释放你的ui上占用的任何资源。为了能够接收到用户离开你UI的通知,
应该重写activity的onTrimMemory()方法(API14,如果是更好的版本可以使用onLowMemory()),在这个方法里面监听UI当前app的UI级别,
如果是TRIM_MEMORY_UI_HIDDEN当用户按下home键时该方法会被调用,这时可以让程序直接退出调用 System.exit0(0);
如何解决gc频繁操作:1.尽量不要在循环里面频繁创建对象,这样的话每循环一次就会销毁,就会调用垃圾回收,gc执行的时候会阻塞线程,导致页面卡顿。
成员变量要在类里面进行定义,这样能减少不必要的gc操作
总结:当系统开始清除lru的进程时,尽管首先按照例如的顺序来管理进程,但他同样会考虑进程的内存使用量,当当前进程使用内存过多的时候同样会被回收掉。
六。网络优化
减少网络请求的频次: 把需要的数据尽量封装在一个集合中,减少请求的次数
减小获取数据包的大小:主要是获取数据的类型现在一般使用json可读性好,占用的资源较小
使用网络缓存: 把一些时效性不高的数据可以适当的进行网络缓存
比如首页的图片可以进行缓存
Android性能优化主要分几大类:1。app启动优化 2.布局优化 3. 响应优化 4.内存优化 5.网络优化
一。性能分析工具
1。Hierarchy Viewer提供了一个可视化的界面来检测布局的层级,让我们可以优化布局层级,删除多余的不必要的层级,提升布局速度
其中下边有三个圆形的图标分别表示测量 、 排版、画布局的性能 绿色表示比50%的都快 黄色表示比50%都慢,红色表示是最慢的
2. TraceView 一个图形化的工具,用来展示和分析方法的执行时间。根据展示的时间来进行方法的优化
二。App启动优化
1.application的onCreate方法中不要做太多的事情
2.首屏activity尽量要简化
三。布局优化
1.尽量减少布局层级和复杂度
去除不必要的父布局
尽量不要嵌套使用RelativeLayout
多用TextView的Drawable
如果HierarchyViewer的层级超过了五层一定要优化
2.使用include来重用布局
3.listview的优化
convertView的复用
引入ViewHolder来减少findViewById();
数据要使用分页加载
四。响应优化
Anr产生时,会在data\anr\traces.txt 生成一个日志文件,可以查看导致anr产生的原因
如何避免:不要在ui线程执行耗时的操作,包括网络请求 数据解析 图片加载,耗时的操作要放在子线程中执行
五。内存优化
主要出现的问题:内存消耗过大,内存泄露,内存抖动最主要的原因是因为gc操作过于频繁,在进行gc的时候所在线程会停止运行
内存消耗过大:Android中常见的就是图片资源消耗过大,因此在加载图片的时候建议使用开发的图片框架,比如universal-image-loader,或者是glide
内存泄露: 1.对context的引用 如果是全部变量引用context这时候该activity的生命周期被延长,这时候可以用application的context。
使当前的activity可以及时的销毁掉,释放内存
总结:根据组件的生命周期合理使用context
2.内部类的问题
当在一个类中new一个内部类的时候,这时内部类会持有外部类的引用,这时候建议使用静态内部类,这样当内部类创建的时候并不需要外部类的引用,
减少外部类的生命周期,使其可以更好的被回收释放资源
如果内部类想调用外部类的方法,可以使用弱引用
代码示例:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_memory_leak);
new DemoHandler(this).sendEmptyMessageDelayed(1, 60 * 1000);
}
private static class DemoHandler extends Handler {
private final WeakReference<HandlerLeakActivity> mActivity;
private DemoHandler(HandlerLeakActivity activity) {
this.mActivity = new WeakReference<>(activity);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
HandlerLeakActivity activity = mActivity.get();
if (activity != null) {
activity.doSomething();
}
}
}
private void doSomething() {
}
3.观察者 listener 广播等注册和销毁没有成对出现,会出现内存泄露
常用的方法有 add\remove register\unregister bind\unbind
4.资源泄露
常见的有:cursor、io、数据库链接等没有及时的关闭
5.bitmap内存泄露
bitmap没有及时回收导致内存泄露
一般情况下可以使用软引用,当内存不够的时候可以回收掉
6.在UI看不见时释放Memory
在用户切换到其他的app,并且你的app页面不可见时,你应该释放你的ui上占用的任何资源。为了能够接收到用户离开你UI的通知,
应该重写activity的onTrimMemory()方法(API14,如果是更好的版本可以使用onLowMemory()),在这个方法里面监听UI当前app的UI级别,
如果是TRIM_MEMORY_UI_HIDDEN当用户按下home键时该方法会被调用,这时可以让程序直接退出调用 System.exit0(0);
如何解决gc频繁操作:1.尽量不要在循环里面频繁创建对象,这样的话每循环一次就会销毁,就会调用垃圾回收,gc执行的时候会阻塞线程,导致页面卡顿。
成员变量要在类里面进行定义,这样能减少不必要的gc操作
总结:当系统开始清除lru的进程时,尽管首先按照例如的顺序来管理进程,但他同样会考虑进程的内存使用量,当当前进程使用内存过多的时候同样会被回收掉。
六。网络优化
减少网络请求的频次: 把需要的数据尽量封装在一个集合中,减少请求的次数
减小获取数据包的大小:主要是获取数据的类型现在一般使用json可读性好,占用的资源较小
使用网络缓存: 把一些时效性不高的数据可以适当的进行网络缓存
比如首页的图片可以进行缓存