Android内存优化

592 阅读2分钟
  1. 不要使用比需求更占空间的基本数据类型
  2. SparseArray代替HashMap,节省内存开销
  3. 基本数据类型的成员,可以全写成static final,static会由编译器调用clinit方法进行初始化
    static final不需要进行初始化工作,打包在dex文件中可以直接调用,并不会在类初始化申请内存
  4. 循环尽量用foreach,少用iterator, 自动装箱尽量少用
  5. 字符串的连接尽量少用加号(+),使用StringBuffer或者StringBuilder替代
  6. 尽量使用IntentService,而不是Service
  7. 非业务需要不要把activity的上下文做参数传递,可以传递application的上下文
  8. 和Activity有关联的对象写成static 如private static Button btn; private static Drawable drawable;
  9. handler.postDelayed(),如果开启的线程需要传入参数,用弱引接收可解决,handler记得清除removeCallbacksAndMessages(null)

枚举优化


public class SHAPE {
    public static final int RECTANGLE=0;
    public static final int TRIANGLE=1;
    public static final int SQUARE=2;
    public static final int CIRCLE=3;

//flag 为true,表示可以多选, value= {限定枚举值value的取值范围}
    @IntDef(flag=true,value={RECTANGLE,TRIANGLE,SQUARE,CIRCLE})
    @Target({ElementType.PARAMETER,ElementType.METHOD,ElementType.FIELD})
//    RetentionPolicy.SOURCE表示资源加载阶段
    @Retention(RetentionPolicy.SOURCE)
    public @interface Model{

    }

    private @Model int value=RECTANGLE;
    public void setShape(@Model int value){
        this.value=value;
    }
    @Model
    public int getShape(){
        return this.value;
    }
}

调用

 SHAPE s=new SHAPE();
        s.setShape(SHAPE.CIRCLE|SHAPE.RECTANGLE);
        System.out.println(s.getShape());

对象池的使用

通过控制对象的调用次数来控制创建对象对内存的影响

package com.example.wuyang.lsn4code;

import android.util.SparseArray;

public abstract class ObjectPool<T> {
    //空闲沲,用户从这个里面拿对象
    private SparseArray<T> freePool;
    //正在使用沲,用户正在使用的对象放在这个沲记录
    private SparseArray<T> lentPool;

    //沲的最大值
    private int maxCapacity;

    public ObjectPool(int initialCapacity, int maxCapacity) {
        //初始化对象沲
        initalize(initialCapacity);
        this.maxCapacity=maxCapacity;
    }

    private void initalize(int initialCapacity) {
        lentPool=new SparseArray<>();
        freePool=new SparseArray<>();
        for(int i=0;i<initialCapacity;i++){
//            对象创建留给调用者完成
            freePool.put(i,create());
        }
    }

    /**
     * 申请对象
     * @return
     */
    public T acquire() throws Exception {

        T t=null;
        synchronized (freePool){
            int freeSize=freePool.size();
            for(int i=0;i<freeSize;i++){
                int key=freePool.keyAt(i);
                t=freePool.get(key);
                if(t!=null){
                    this.lentPool.put(key,t);
                    this.freePool.remove(key);
                    return t;
                }
            }
            //如果没对象可取了
            if(t==null && lentPool.size()+freeSize<maxCapacity){
                //这里可以自己处理,超过大小
                if(lentPool.size()+freeSize==maxCapacity){
                    throw new Exception();
                }
                t=create();
                lentPool.put(lentPool.size()+freeSize,t);


            }
        }
        return t;
    }

    /**
     * 回收对象
     * @return
     */
    public void release(T t){
        if(t==null){
            return;
        }
        int key=lentPool.indexOfValue(t);
        //释放前可以把这个对象交给用户处理
        restore(t);

        this.freePool.put(key,t);
        this.lentPool.remove(key);

    }

    protected  void restore(T t){

    }


    protected abstract T create();

    public ObjectPool(int maxCapacity) {
        this(maxCapacity/2,maxCapacity);
    }

}
package com.example.wuyang.lsn4code;

public class MyObjectPool extends ObjectPool{
    public MyObjectPool(int initialCapacity, int maxCapacity) {
        super(initialCapacity, maxCapacity);
    }

    public MyObjectPool(int maxCapacity) {
        super(maxCapacity);
    }

    @Override
    protected Object create() {//LRU
        return new Object();
    }
}

调用:

 MyObjectPool pool=new MyObjectPool(2,4);
        Object o1= null;
        Object o2= null;
        Object o3= null;
        Object o4= null;
        Object o5= null;
        try {
            o1 = pool.acquire();
            o2 = pool.acquire();
            o3 = pool.acquire();
            o4 = pool.acquire();
            o5 = pool.acquire();
            Log.i("申请对象1:",o1.hashCode()+"");
            Log.i("申请对象2:",o2.hashCode()+"");
            Log.i("申请对象3:",o3.hashCode()+"");
            Log.i("申请对象4:",o4.hashCode()+"");
            Log.i("申请对象5:",o5.hashCode()+"");
        } catch (Exception e) {
            e.printStackTrace();
            Log.e("申请对象超过最大值:", e.toString() );
        }

调用结果