【问题标题】:Java singleton with weak reference具有弱引用的 Java 单例
【发布时间】:2017-07-17 11:19:59
【问题描述】:

这是我的弱引用单例类。

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;

  }

【问题讨论】:

  • 你的主要错误是首先取消了单例模式。 stackoverflow.com/questions/137975/…
  • 从哪里调用最后一段代码?
  • @EnamulHaque 来自活动。大多数相同的代码运行良好。有时我会变得空虚。
  • 您是否经常调用该活动..例如重复2-3次
  • @EnamulHaque 不。

标签: java android singleton weak-references


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    弱引用对象,不会阻止其所指对象被终结、终结和回收。

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

    那么当我们使用弱引用的时候,同时或者稍后的某个时间,它会将那些新清除的注册到引用队列中的弱引用加入队列。

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

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

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

    【讨论】:

    • 嗨...有其他解决方案吗?如果有请分享。
    • 是的,将分享解决方案。
    【解决方案3】:

    解决方法如下。

    public static synchronized HandheldMapViewProvider getInstance(){
    HandheldMapViewProvider mapProvider = mInstance == null ? null :mInstance.get();
    
    if(mapProvider == null){
    
       mInstance = new WeakReference<HandheldMapViewProvider>(mapProvider =new 
       HandheldMapViewProvider());
    }
    
    return mapProvider;
    
    }
    

    【讨论】:

      猜你喜欢
      • 2021-07-19
      • 1970-01-01
      • 2013-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-12
      • 1970-01-01
      • 2020-02-05
      相关资源
      最近更新 更多