android性能优化之渲染优化和内存优化

卡顿:Android系统每隔16ms发出VSYNC信号,触发对UI进行渲染。如果你的某个操作是大于16ms,系统在得到VSYNC信号的时候就无法进行正常的渲染,这样就发生了丢帧即卡顿现象。

ANR:主线程在特定的时间内没有做完特定的事情, 通常在如下两种情况下会弹出ANR对话框:

  • 5s内无法响应用户输入事件(例如键盘输入, 触摸屏幕等).
  • BroadcastReceiver在10s内无法结束

一、渲染优化

1、减少布局层级-扁平化设计

  • 首先应当考虑布局层级最小的方案。
  • 布局层级相同时,就应当选取合适的父容器,一般来说,有以下几点经验:
  • 选取的优先级为:FrameLayout、不带layout_weight参数的LinearLayout、RelativeLayout,这里选取的标准为带有layout_weight的LinearLayout或者RelativeLayout会测量两次。
  • 当使用LinearLayout时,应当尽量避免使用layout_weight参数。
  • 避免使用RelativeLayout嵌套RelativeLayout。
  • 如果允许,那么可以使用Google的ConstraintLayout布局。

2、measure、layout、draw 的耗时时间

不要在onMeasure、onLayout、onDraw方法中频繁地创建对象,例如Paint、Path这样的类。

3、过度绘制

设置/辅助功能/开发者选项/,点击调试GPU过度绘制选项打开开关之后,可以看到界面当中会出现各种颜色的矩形,这就对应着过度绘制的等级,颜色越深,表明过度绘制越严重。为避免过度绘制,这就要求

  • 减少布局层级
  • 去掉不必要的背景(windows默认背景以及Layout背景)
  • 使用ViewStub代替需要GONE的异常错误页
  • 没有用的父布局时指没有背景绘制或者没有大小限制的父布局,这样的布局不会对UI效果产生任何影响,我们可以把没有用的父布局,通过<merge/>标签合并来减少UI的层次
  • 通过canvas.clipRect()来 帮助系统识别那些可见的区域

二、内存优化-内存泄露

1.资源对象没关闭

  • 数据库Cursor未关闭
  • 调用registerReceiver后未调用unregisterReceiver()

  • 未关闭InputStream/OutputStream

  • Bitmap使用后未调用recycle()

  • acitivity中timer和TimerTask未在onDestroy()时cancel掉

  • 无用集合中的对象未清理

  • acitivity中属性动画未在onDestroy()时cancel掉

  • acitivity中属性动画未在onDestroy()时cancel掉

2.作用域不一样,导致对象不能被垃圾回收器回收

  • 不要保留对Context-Activity长时间的引用(对Activity的引用的时候,必须确保拥有和Activity一样的生命周期);

  • 使用Context-Application来替代Context-Activity用于创建单例、静态变量等长时间对象。

  • 对于引用生命周期不一样的对象,可以用软引用或弱引用SoftReferner WeakReferner,如果你不想控制内部类的生命周期,应避免在Activity中使用非静态的内部类,而应该使用静态的内部类,并在其中创建一个对Activity的弱引用(Handler应该申明为静态对象, 并在其内部类中保存一个对外部类的弱引用)。

3.内存压力过大

  • 使用Adapter时,没有使用系统缓存的convertview和viewholder

  • 图片资源加载过多,超过内存使用空间,例如Bitmap 的使用

  • 使用缓存技术,比如LruCache、DiskLruCache、对象重复并且频繁调用可以考虑对象池

猜你喜欢

转载自blog.csdn.net/u013795543/article/details/81611153