android app 性能优化(1)---- 运行缓慢

来源:互联网 发布:滑雪服品牌 知乎 编辑:程序博客网 时间:2024/06/05 17:07

现象观察

首先从视觉上发现某个页面不流畅,何谓不流畅,如上下滑动页面时页面无法立马做出响应、滑动的过程中有卡顿。

原因分析

先找个理论依据,用户每一个手势都会new一个Runnable丢进主线程的执行队列中(无确切依据,只是记得以前看的某篇博文中提及的内容),那么原因就有以下两种。一种可能是主线程队列中的任务太多导致出队速度太慢。一种可能是出队速度不慢但是执行太慢,何谓执行太慢,就是CPU与内存无法快速响应大量的界面绘制需求。那么有两种可能导致执行慢,一是 CPU与内存资源消耗殆尽,二是存在过度绘制。

解决方案

对应第一种推测的解决办法是:1.避免在主线程中执行太多任务(存在三种类型的任务,一是必须放在主线程执行的任务;二是不应该放在主线程执行的任务,三是可以优化处理放在工作线程执行的,我们最终目的还是尽可能减少主线程中的任务)。2.避免在主线程中执行耗时任务。对应第二种推测的解决办法是:1.避免不必要的内存使用。2.及时回收不再使用的内存。3.避免不必要的 CPU消耗。4.及时关闭不再需要的 CPU消耗操作。5.避免过度绘制。

应用场景

一,计时器    (1)从计时器数量着手。比如购物车的倒计时不只是在购物车页面展示,需要在很多页面都同步展示这个倒计时,不太好的设计是每个展示页面都开启一个倒计时,好的设计是开启一个全局倒计时,哪个页面需要展示就去注册监听,页面销毁时解除监听。    (2)从计时器实现方式着手。很多代码中是用 handler往主线程中发送 message实现计时器,这种方式会加重主线程的负担。可以用开启工作线程的方式取代前者(这种方法只适用于无需刷新 UI的情况,如果需要刷新 UI还是无法避免使用 hanlder)。二,文件读写    频繁的文件读写操作最好放在工作线程三,避免不必要的内存使用    (1)依赖注入框架最好使用Dagger2。它不通过反射扫描应用代码,所以不会产生不必要的CPU使用和内存消耗,其他的依赖注入框架则相反。    ![来自 android developer](http://img.blog.csdn.net/20171117143257047?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHFmc2hhcmtz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)    [android developer 链接:Use Dagger 2 for dependency injection](https://developer.android.com/topic/performance/memory.html#DependencyInjection)    (2)谨慎的使用抽象编程。抽象编程意味着更多的代码,更多的CPU占用与内存销毁。如果抽象编程不能带来明显的好处你应该避免使用它。    比如枚举占用的内存是静态常量的两倍,android中应该严格的避免使用它。    [android developer 链接:Be careful with code abstractions](https://developer.android.com/topic/performance/memory.html#Abstractions)    (3)使用优化过的数据集合。用android优化过的 SparseXXX取代java自带的集合类,如java自带 HashMap要求键值对都是对象,无法使用基础类型。四,使用完 Bitmap及时调用 bitmap.recycle()方法回收。bitmap对象无法 new出来,是通过 BitmapFactory.decodeXXX解码出来的。它的内存在虚拟机与 kernel中各有一部分,前者虚拟机自动回收,后者需要手动调用 recycle方法回收(无确切依据,只是从一篇博文中读到;2.3以后不再需要手动调用)五,使用缓存机制避免不必要的网络请求,文件读取,图片加载。六,僵尸线程。不再使用的线程要及时关闭,避免浪费 CPU资源。七,自定义控件时避免在onDraw里面 new对象。八,不要在RecyclerView或 listView的 header里面加载太多资源、控件。因为 header是一次性加载的,如果元素过多会导致第一次显示的时候很慢。
原创粉丝点击