Android程序性能优化

Android程序性能优化

主要从三个方面:
  1.UI优化
   2.提高线程的并发
  3.内存方面:从防止内存泄漏和内存浪费两个

UI

  • 布局文件
    1.减少布局的层级:
        举例,自定义ViewGroup如果需要使用布局文件,布局文件里使用取代XXXLayout,可以减少一层布局;
    2.减少使用match_parent,ViewGroup尽量少用wrap_content,控件的宽高尽量使用固定值
       这样可以减少measure,layout过程的计算的复杂度
      如果某个ViewGroup有10个子View,ViewGroup宽高设置了wrap_content,10个子View中5个宽高设置了固定值,
        另外五个设置了match_parent,
      在mearsure过程中,mearsure事件传入ViewGroup,ViewGroup遍历10个子View,把measure事件传给它们, 得
        到宽高结果返回给ViewGroup,ViewGroup根据结果获得最大的宽,最大的高,再把最大的宽和高传给那
        五个子View
      如果都设置成固定值,就可以measure中反复遍历的过程
    3.ViewStub 用懒加载的方式

提高程序中的线程并发性

  • 对共享资源的处理
      当多线程对同一资源操作时会产生线程安全的问题:
        根据共享资源的情况:
          1.如果共享资源是boolean,Integer这种基本数据类型,
            可以采用volatile或volatile+AutomicXXX(如AutuomicInteger)的方式保证并发的线程安全;
            volatile可以保证线程对共享资源的原子操作,对其他的线程具备可见性;
            当共享资源的操作有非原子性操作时,用AutomicXXX封装共享资源;
          2.如果共享资源是对象,
            使用sychronized或lock,保证读并发,写同步
            在某个线程进行写操作时,通过修改标志位的方式,使得后面的读写线程阻塞,当该线程完成写操作之
              后,将阻塞的线程通过系统唤醒,
            线程的阻塞和唤醒,可以通过wait-notify实现。
          3.如果共享资源是集合的话,
            Java提供了CopyOnWrite,Concurrent,Blocking三种策略提高并发性,实现读写分离,读并发,写同步:
             1.CopyOnWrite, 用于读多写少的情况,利用写时复制,提高了写时读并发
            2.Concurrent, 使用分段锁的方式,不同分段的读写并发,相同分段的读并发,写同步
            3.Blocking, 解决限制容量的容器的存取问题,类似生产者消费者模式,
              容器为空时,取线程阻塞,直到容器不为null,线程会被唤醒
              容器满时,存线程阻塞,直到容器不满,线程会被唤醒
  • 根据具体情况选择使用ThreadPool,还是new Thread
        如果任务只是偶尔要在子线程中运行,采用new Thead;
        如果任务经常需要在子线程中运行,采用ThreadPool;

内存

避免内存浪费

  • 选择合适的数据结构
      1.ArrayMap,SparseMap是Android为了内存优化提供的HashMap的替代品;
      2.ArrayList多次删除后,可以使用trimToSize()减少ArrayList封装的数组的Length;

  • 缓存
      缓存分为两类:
        1.缓存空对象,
          当需要对象时,从缓存中取出空对象;
          当对象使用完成后,将对象数据清空,放入缓存;
          这样做的目的是需要经常创建某个类的对象时,可以采用这种缓存,减少new和GC
          举例,ThreadPool, Message.obtain都是采用了这种缓存
        2.缓存带有数据的对象,
          Glide中针对Bitmap的缓存
          OKHttp中针对Request-Response,Connection长链接的缓存

避免内存泄漏

   1.使用软弱引用
  2.当遇到使用传统的观察者模式时,
      例如,EventBus,BroadcastReceiver,在销毁或置空观察者或被观察者时,一定先要解除两者之间的绑定关系
  3.做到对象与对象之间的解藕
    通过方法传入的对象,不要保存它的全局引用

  Class A {
      methodA() {... }
  }
  Class B {
      A a;
      B(A a) {
          this.a = a;
      }
      
      methodB() {
          a.methodA();
      }
  }
  
  A a = new A();
  B b = new B(a);
  a = null;

虽然a = null,但仍有引用指向A对象

   class A {
       methodA() {....}
   }
   class B {
       methodB(A a) {
           a.methodA();
       }
   }

这样,A与B解耦,
可以把methodA,methodB抽象

       new B() {
       
           void methodB(A a) {
               a.methodA();
           }
       }.methodB(new A() {
           void methodA() {
               ... ...
           }
       });

而传统的观察者模式

   class Observer {
       void update() {
           
       }
   }
   class Observable {
       List<Observer> observers;
       
       void register(Observer oberser) {
           observers.add(oberser);
       }
       void unregister(Observer oberser) {
           observers.remove(oberser);
       }
       
       void update() {
           for(Observer obs: observers) {
               obs.upate();
           }
       }
   }

这样很容易造成内存泄漏,
RxJava实际上,使用了多种方式实现了Observer与Observable之间的解耦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值