具有弱引用的Java单例

时间:2017-07-17 11:20:00

标签: java android singleton weak-references

这是我的单例类,弱引用。

public class HandheldMapViewProvider  {

    private static WeakReference<HandheldMapViewProvider> mInstance = null;

    private HandheldMapViewProvider(){

    }

    public static synchronized WeakReference<HandheldMapViewProvider> getInstance(){
       if(mInstance == null){
         mInstance = new WeakReference<HandheldMapViewProvider>(new HandheldMapViewProvider());
       }
       return mInstance;
    }

    public void onprint(String data){
        Log.D("TAG",data)
    }


}

上述课程的用法如下。

 private WeakReference<HandheldMapViewProvider> hereMapViewProvider;

 public void onprint(){
     hereMapViewProvider = HandheldMapViewProvider.getInstance();
     hereMapViewProvider.get().onprint("somevalue");
 }

调用onprint方法时第一次应用程序崩溃有时因为get()为空。

任何想法,我做错了。它没有一直发生。

解决方案如下。

public static synchronized HandheldMapViewProvider getInstance(){
  HandheldMapViewProvider mapProvider = mInstance == null ? null :mInstance.get();

  if(mapProvider == null){

       mInstance = new WeakReference<HandheldMapViewProvider>(mapProvider =new HandheldMapViewProvider());
   }

   return mapProvider;

  }

3 个答案:

答案 0 :(得分:0)

问题是您将HandheldMapViewProvider存储为WeakReference。 垃圾收集器清除该值,因此get()返回null。

要避免此行为,只需删除WeakRreference实现并将HandheldMapViewProvider存储为“常规”静态字段。

答案 1 :(得分:0)

弱引用对象,它们不会阻止它们的指示物被最终化,最终化,然后回收。

垃圾收集器在某个时间点确定哪个对象是弱可达的。那时它将原子地清除对该对象的所有弱引用以及对任何其他弱可达对象的所有弱引用,通过一系列强引用和软引用可以从该对象到达该对象。同时,它将声明所有以前弱可达的对象都可以最终确定。

当我们使用弱引用时,在同一时间或稍后它会将那些新引用的弱引用排入队列。

垃圾收集器正在发生......所以我们不知道什么时候会发生......

您可以使用try catch块保存代码以避免崩溃..

public void onprint(){
    hereMapViewProvider = HandheldMapViewProvider.getInstance();
    try{
        hereMapViewProvider.get().onprint("somevalue");
    }catch(Exception e){
      Log.e("Err", e.toString()+"");
    }
}

答案 2 :(得分:0)

解决方案如下。

public static synchronized HandheldMapViewProvider getInstance(){
HandheldMapViewProvider mapProvider = mInstance == null ? null :mInstance.get();

if(mapProvider == null){

   mInstance = new WeakReference<HandheldMapViewProvider>(mapProvider =new 
   HandheldMapViewProvider());
}

return mapProvider;

}