由于手机硬件的限制,内存和CPU都无法像pc一样具有超大的内存,Android手机上,过多的使用内存,会容易导致oom,过多的使用CPU资源,会导致手机卡顿,甚至导致anr。主要是从一下几部分进行优化: 布局优化,绘制优化,内存泄漏优化,网络优化,响应速度优化,listview优化,bitmap优化,线程优化
布局优化工具 hierarchyviewer,解决方式:
1、删除无用的空间和层级。2、选择性能较低的viewgroup,如Relativelayout,如果可以选择Relativelayout也可以使用LinearLayout,就优先使用LinearLayout,因为相对来说Relativelayout功能较为复杂,会占用更多的CPU资源。3、使用标签<include/>重用布局,<Merge/>减少层级,<viewStub/>进行预加载,使用的时候才加载。注意使用wrap_content,会增加measure计算成本;删除控件中无用属性 绘制优化绘制优化指view在ondraw方法中避免大量的耗时操作,由于ondraw方法可能会被频繁的调用。 过度绘制是指在屏幕上的某个像素在同一帧的时间内被绘制了多次。在多层次重叠的 UI 结构中,如果不可见的 UI 也在做绘制的操作,就会导致某些像素区域被绘制了多次,从而浪费了多余的 CPU 以及 GPU 资源。我们可以通过开启手机的过渡绘制功能来检测页面是否被过度绘制。
1、ondraw方法中不要创建新的局部变量,ondraw方法被频繁的调用,很容易引起GC。2、ondraw方法不要做耗时操作。布局上的优化,移除 XML 中非必须的背景,移除 Window 默认的背景、按需显示占位背景图片。自定义View优化,使用 canvas.clipRect()来帮助系统识别那些可见的区域,只有在这个区域内才会被绘制。 内存泄露优化Android内存泄露及管理 (1)内存溢出(OOM)和内存泄露(对象无法被回收)的区别。 (2)引起内存泄露的原因 (3) 内存泄露检测工具 ------>LeakCanary
内存溢出 out of memory:是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。内存溢出通俗的讲就是内存不够用。内存泄露 memory leak:是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光内存泄露原因: 一、Handler 引起的内存泄漏。 解决:将Handler声明为静态内部类,就不会持有外部类SecondActivity的引用,其生命周期就和外部类无关, 如果Handler里面需要context的话,可以通过弱引用方式引用外部类 二、单例模式引起的内存泄漏。 解决:Context是ApplicationContext,由于ApplicationContext的生命周期是和app一致的,不会导致内存泄漏 三、非静态内部类创建静态实例引起的内存泄漏。 解决:把内部类修改为静态的就可以避免内存泄漏了 四、非静态匿名内部类引起的内存泄漏。 解决:将匿名内部类设置为静态的。 五、注册/反注册未成对使用引起的内存泄漏。 注册广播接受器、EventBus等,记得解绑。 六、资源对象没有关闭引起的内存泄漏。 在这些资源不使用的时候,记得调用相应的类似close()、destroy()、recycler()、release()等方法释放。 七、集合对象没有及时清理引起的内存泄漏。 通常会把一些对象装入到集合中,当不使用的时候一定要记得及时清理集合,让相关对象不再被引用。 网络优化 图片网络优化 例如,针对网络情况,返回不同的图片数据,一种是高清大图,一种是正常图片,一种是缩略小图。当用户处于wifi下给控件设置高清大图,当4g或者3g模式下加载正常图片,当弱网条件下加载缩略图。 网络数据优化 连接复用:节省连接建立时间,如开启 keep-alive。对于Android来说默认情况下HttpURLConnection和HttpClient都开启了keep-alive。只是2.2之前HttpURLConnection存在影响连接池的Bug请求合并:即将多个请求合并为一个进行请求,比较常见的就是网页中的CSS Image Sprites。如果某个页面内请求过多,也可以考虑做一定的请求合并。减少请求数据的大小:对于post请求,body可以做gzip压缩的,header也可以做数据压缩。返回数据的body也可以做gzip压缩,body数据体积可以缩小到原来的30%左右。 异常拦截优化 在获取数据的流程中,访问接口和解析数据时都有可能会出错,我们可以通过拦截器在这两层拦截错误。 在访问接口时,我们不用设置拦截器,因为一旦出现错误,Retrofit会自动抛出异常。比如,常见请求异常404,500,503等等。在解析数据时,我们设置一个拦截器,判断Result里面的code是否为成功,如果不成功,则要根据与服务器约定好的错误码来抛出对应的异常。比如,token失效,禁用同账号登陆多台设备,缺少参数,参数传递异常等等。 响应优化主线程不能做耗时操作,触摸事件5s,广播10s,service20s。
listview优化1、getview方法中避免耗时操作。 2、view的复用和viewholder的使用。 3、滑动不适合开启异步加载。 4、分页处理数据。 5、图片使用三级缓存。
Bitmap优化1、等比例压缩图片。 2、不用的图片,及时recycler掉
线程优化线程优化的思想是使用线程池来管理和复用线程,避免程序中有大量的Thread,同时可以控制线程的并发数,避免相互抢占资源而导致线程阻塞。
其它优化1、少用枚举,枚举占用空间大。 2、使用Android特有的数据结构,如SparseArray来代替hashMap。 3、适当的使用软引用和弱引用。