1

Here is my singleton class with weak reference.

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)
    }


}

Usage of above class is as follow.

 private WeakReference<HandheldMapViewProvider> hereMapViewProvider;

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

While calling onprint method first time app get crash sometimes due to get() is null.

Any idea where i am doing it wrong. its not happening all time.

Solution is as below.

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

  if(mapProvider == null){

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

   return mapProvider;

  }
Keyur Thumar
  • 608
  • 7
  • 19

3 Answers3

0

The problem is that you store HandheldMapViewProvider as a WeakReference. The garbage collector clears the value so get() returns null.

To avoid this behavior just drop the WeakRreference implementation and store the HandheldMapViewProvider as a "regular" static field.

Yossi Segev
  • 607
  • 5
  • 12
0

Weak reference objects, which do not prevent their referents from being made finalizable, finalized, and then reclaimed.

Garbage collector determines at a certain point in time that which object is weakly reachable. At that time it will atomically clear all weak references to that object and all weak references to any other weakly-reachable objects from which that object is reachable through a chain of strong and soft references. At the same time it will declare all of the formerly weakly-reachable objects to be finalizable.

When we use Weak reference then, At the same time or at some later time it will enqueue those newly-cleared weak references that are registered with reference queues.

It is happening form Garbage Collector...So We don't know when it will happen ..

You can save your code by using try catch block to avoid crashing ..

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

Solution is as below.

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

if(mapProvider == null){

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

return mapProvider;

}
Keyur Thumar
  • 608
  • 7
  • 19