1

I have a singleton class which I first instantiate in 1 activity, then use it in 2 other activities. When the 2nd activity loads, the instance becomes null, where is was not null before.

Here is the code for the singleton class:

public class RestaurantMenuHolder{

    private static RestaurantMenuHolder mInstance = null;
    public static ArrayList<RestaurantMenuObject> restaurantMenu;

    public static RestaurantMenuHolder getInstance(ArrayList<RestaurantMenuObject> restaurantMenu){
        if(mInstance == null){
            mInstance = new RestaurantMenuHolder(restaurantMenu);
        }
        return mInstance;
    }

    public static RestaurantMenuHolder getInstance(){
        return mInstance;
    }

    private RestaurantMenuHolder(ArrayList<RestaurantMenuObject> restaurantMenu){
        this.restaurantMenu = restaurantMenu;
    }

    public static int getCount(){
        return restaurantMenu.size();
    }

}

I have tried adding synchronized to the getInstance methods, the constructor and getCount, but I still get null when the second activity loads. Does anyone know why or how the singleton would suddenly become null?

I can provide code for the activities if required.

EDIT: More Code

When I initialize the singleton: I run holder = RestaurantMenuHolder.getInstance(restaurantMenu); where restaurantMenu is an arrayList. I initialize this to store data. This is verified to work, the singleton is not null at this point.

In the first activity that I use the singleton, I run RestaurantMenuHolder menuHolder = RestaurantMenuHolder.getInstance(); in onCreateView for the fragment. I use this instance to retrieve the data previously stored. The singleton is also verified to work here.

When the second activity is started, the singleton becomes null, but not immediately. I run menuHolder = RestaurantMenuHolder.getInstance(); again in the second activity and retrieve some more data, all of which is valid.

The problem appears to occur in the ImageAdapter. I use a slidingMenu with an ImageAdapter for both activities. The singleton works for the first activity and is not null, but becomes null when I try to use it again in the second activity.

Here is code from the ImageAdapter:

public class ImageAdapter extends BaseAdapter{

    private static LayoutInflater inflater = null;
    private ViewHolder holder;
    private String id;
    private RestaurantMenuHolder menuHolder;
    private RestaurantLocationHolder locationHolder;
    private Context context;

    private String[] sliding_list = {"Home", "Skip to Menu", "Location & Hours", "About Us"};
    Typeface tf;

    public ImageAdapter(Context context, String id){
        this.context = context;
        inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        this.id = id;
        tf = Typeface.createFromAsset(context.getAssets(),
                "Roboto-Light.ttf");
        menuHolder = RestaurantMenuHolder.getInstance();
        locationHolder = RestaurantLocationHolder.getInstance(context);
        MenuUtilities.setImageHash();
    }

    @Override
    public int getCount() {
        if(id == "menu"){
            Log.d((menuHolder == null) + "", "MENUHOLDER NULL");
            return menuHolder.getCount();
        } else if (id == "location") {
            return locationHolder.getCount();
        } else {
            return sliding_list.length;
        }
    }
... more code

When the second activity is started, return menuHolder.getCount(); results in a NullPointerException. Log.d((menuHolder == null) + "", "MENUHOLDER NULL"); returns true at this point, when it had previously returned false.

Corey Wu
  • 1,209
  • 1
  • 22
  • 39
  • 2
    Why is your `restaurantMenu` not `private` and `static`? Also, did you verify that the instance is actually created? General notice: you must support that the singleton becomes null, as Android may stop and re-create your activity (without re-creating parent activities). – dst Aug 23 '13 at 02:25
  • Add some more code from your activity – Ahmed Aug 23 '13 at 02:28
  • 2
    Your singleton should not be accepting an arraylist in getInstance. Or, if it is, it needs to be doing something with it *every* time. Not just when `mInstance` is null. Also `restarauntMenu` should be private, and should not be static, as @dst says. Please add more code. – William Morrison Aug 23 '13 at 02:34
  • Thanks for the input! `restaurantMenu` being `static` was a mistake that I forgot to revert; I was testing whether or not making it `static` would solve things. I changed `restaurantMenu` to private and added a getter method, but the error still occurs. I have verified that the singleton is not null when used in the first activity, and becomes null when I try to use it in the second. In my singleton, I pass in the arrayList to store it when I initialize it. Is there a reason I need to do something with it every time? I call `getInstance()` without the arrayList to retrieve it. – Corey Wu Aug 23 '13 at 03:09

1 Answers1

0

just Do single change and will work

public class RestaurantMenuHolder{

    private static RestaurantMenuHolder mInstance = null;
    public static ArrayList<RestaurantMenuObject> restaurantMenu;

    public static RestaurantMenuHolder getInstance(ArrayList<RestaurantMenuObject> restaurantMenu){
        if(mInstance == null){
            mInstance = new RestaurantMenuHolder(restaurantMenu);
        }
        return mInstance;
    }

    public static RestaurantMenuHolder getInstance(){
        if(mInstance == null){
            mInstance = new RestaurantMenuHolder(restaurantMenu);
        }
        return mInstance;
    }

    private RestaurantMenuHolder(ArrayList<RestaurantMenuObject> restaurantMenu){
        this.restaurantMenu = restaurantMenu;
    }

    public static int getCount(){
        return restaurantMenu.size();
    }

}
Biraj Zalavadia
  • 28,348
  • 10
  • 61
  • 77