Android面试相关

Android 四种引用比较与源码分析

2018-04-04  本文已影响84人  杨充211

目录介绍

特此说明

0.关于四种引用

0.1 引用说明

0.2 关于Java下ref包和Android下ref包

1.强引用

1.0 关于强引用引用的场景

1.1 强引用介绍

1.2 强引用的特点

1.3 注意相互引用情况

2.软引用

2.0 关于SoftReference软引用

2.1 软引用应用场景

2.2 软引用的简单使用

MyObject aRef = new  MyObject();
SoftReference aSoftRef = new SoftReference(aRef);
MyObject anotherRef = (MyObject)aSoftRef.get();

2.3 软引用的特点

ReferenceQueue queue = new  ReferenceQueue();
SoftReference  ref = new  SoftReference(aMyObject, queue);
SoftReference ref = null;
while ((ref = (EmployeeRef) q.poll()) != null) {
    // 清除ref
}

2.4 实际应用案例

View view = findViewById(R.id.button);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);
Drawable drawable = new BitmapDrawable(bitmap);
SoftReference<Drawable> drawableSoftReference = new SoftReference<Drawable>(drawable);
if(drawableSoftReference != null) {
    view.setBackground(drawableSoftReference.get());
}

2.5 注意避免软引用获取对象为null

3.弱引用

3.0 关于WeakReference弱引用

3.1 WeakReference:防止内存泄漏,要保证内存被虚拟机回收

3.2 弱引用解决办法

private MyHandler handler = new MyHandler(this);
private static class MyHandler extends Handler{
    WeakReference<FirstActivity> weakReference;
    MyHandler(FirstActivity activity) {
        weakReference = new WeakReference<>(activity);
    }

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        switch (msg.what){
        }
    }
}

3.3 弱引用实际应用案例

4.虚引用

4.0 关于PhantomReference类虚引用

4.1 Android实际开发中没有用到过

5.四种引用其他介绍

5.1 弱引用和软引用区别

5.2 使用软引用或者弱引用防止内存泄漏

5.3 到底什么时候使用软引用,什么时候使用弱引用呢?

5.4 四种引用用一张表总结[摘自网络]

image

6.源码分析

6.1 首先看看如何通过弱引用加载图片

image

6.2 看看Reference的源代码

public abstract class Reference<T> {

    private static boolean disableIntrinsic = false;
    private static boolean slowPathEnabled = false;
    volatile T referent;         /* Treated specially by GC */
    final ReferenceQueue<? super T> queue;
    Reference queueNext;
    Reference<?> pendingNext;

    //返回此引用对象的引用。如果这个引用对象有由程序或垃圾收集器清除,然后此方法返回
    public T get() {
        return getReferent();
    }

    private final native T getReferent();

    //清除此引用对象。调用此方法不会将对象加入队列
    public void clear() {
        this.referent = null;
    }

    //是否引用对象已进入队列,由程序或垃圾收集器。
    //如果该引用对象在创建队列时没有注册,则该方法将始终返回
    public boolean isEnqueued() {
        return queue != null && queue.isEnqueued(this);
    }

    //添加引用对象到其注册的队列,如果他的方法是通过java代码调用
    public boolean enqueue() {
       return queue != null && queue.enqueue(this);
    }

    Reference(T referent) {
        this(referent, null);
    }

    Reference(T referent, ReferenceQueue<? super T> queue) {
        this.referent = referent;
        this.queue = queue;
    }
}

6.3 看看ReferenceQueue的enqueue函数

6.4 看看ReferenceQueue的enqueueLocked(Reference)函数

6.5 接着看看ReferenceQueue.isEnqueued()代码

boolean isEnqueued(Reference<? extends T> reference) {
    synchronized (lock) {
        return reference.queueNext != null && reference.queueNext != sQueueNextUnenqueued;
    }
}

6.6 那么enqueueLocked(Reference)函数中的Cleaner是做什么的

6.7 软引用SoftReference源码

public class SoftReference<T> extends Reference<T> { 
    static private long clock; 
    private long timestamp; 
    public SoftReference(T referent) { 
        super(referent); 
        this.timestamp = clock; 
    } 
    public SoftReference(T referent, ReferenceQueue<? super T> q) { 
        super(referent, q); 
        this.timestamp = clock; 
    } 
    public T get() { 
        T o = super.get(); 
        if (o != null && this.timestamp != clock) 
            this.timestamp = clock; 
        return o; 
    } 
} 

6.8 弱引用WeakReference源码

public class WeakReference<T> extends Reference<T> { 
    public WeakReference(T referent) { 
        super(referent); 
    } 
    public WeakReference(T referent, ReferenceQueue<? super T> q) { 
        super(referent, q); 
    } 
} 

6.9 虚引用PhantomReference源码

public class PhantomReference<T> extends Reference<T> { 
    public T get() { 
        return null; 
    } 
    public PhantomReference(T referent, ReferenceQueue<? super T> q) { 
        super(referent, q); 
    } 
}

7.关于其他

7.1 关于参考案例

7.2 关于版本说明

7.3 关于我的博客

上一篇下一篇

猜你喜欢

热点阅读