由于手机硬件的限制,内存和CPU都无法向PC一样拥有非常大的内存。在Android手机上,过多的使用内存,很容易导致oom(Out of memory),过多的使用CPU资源,很容易导致手机卡顿,甚至是anr(Application no responed),因此,我们从以下这几部分进行优化:
布局优化, 绘制优化,内存泄漏优化,响应速度优化,listView优化,bitmap优化,线程优化
布局优化:工具hierarchyviewer,解决方式
- 删除无用的空间和层级
- 选择性能较低的ViewGroup,例如RelativeLayout,如果可以使用LiinearLayout就优先使用它,因为相对来说RelativeLayout功能较为复杂,会占用更多的CPU资源。
- 使用标签重用布局,减少层级,进行预加载,使用的时候再去加载。
绘制优化:是指view在onDraw方法中避免大量的耗时操作,因为onDraw方法可能会被频繁调用
- onDraw方法中不要创建新的局部变量,该方法被频繁调用很容易引起GC
- onDraw方法中不要做耗时操作
内存泄漏优化:常见引起内存泄漏的原因
- 非静态内部类的静态实例容易造成内存泄漏:即一个类中如果你不能控制其中内部类的生命周期(比如Activity中的Handler等),则尽量使用静态内部类或弱引用来处理(比如ViewRoot的实现)。
- Bitmap在不使用的情况下没有回调recycle()方法释放内存资源。
- 在构造Adapter时,没有使用缓存的convertView。
- 警惕线程未终止造成的内存泄露;譬如在Activity中关联了一个生命周期超过Activity的Thread,在退出Activity时切记结束线程。一个典型的例子就是HandlerThread的run方法是一个死循环,它不会自己结束,线程的生命周期超过了Activity生命周期,我们必须手动在Activity的销毁方法中调用thread.getLooper().quit();才不会泄露。
- 对象的注册与反注册没有成对出现造成的内存泄露;譬如注册广播接收器、注册观察者(典型的比如数据库的监听)等。
- 创建与关闭没有成对出现造成的泄露;比如Cursor资源必须手动关闭,WebView必须手动销毁,流等对象必须手动关闭等。
- 不要在执行频率很高的方法或者循环中创建对象(比如onMeasure),可以使用HashTable等创建一组对象容器从容器中取那些对象,而不用每次new与释放。
- 避免代码设计模式的错误造成内存泄露;譬如循环引用,A持有B,B持有C,C持有A,这样的设计谁都得不到释放。
响应优化:主线程不能做耗时操作,触摸事件响应5s,广播接收器处理10s,service 20s
ListView优化:
- getView方法避免耗时操作
- view的复用和viewHolder的使用
- 滑动时不适合开启异步加载
- 可以分页处理数据
- 图片使用三级缓存
Bitmap优化:
- 等比例压缩图片
- 不用的图片,及时recycler
线程优化:
线程优化的思想是使用线程池来管理和复用线程,避免程序中有大量的Thread,同时可以控制线程的并发数,避免相互抢占资源而导致线程阻塞。
其他优化:
- 少用枚举:枚举占用空间大
- 使用Android特有的数据结构,如SparseArray来代替HashMap
- 适当的使用软引用和弱引用