简体   繁体   中英

Instance of Singleton null

I use some singletons in my Android app. From my GlobalApp ( extends Application ) class in onCreate() they are initialized like this:

public class GlobalApp extends Application{


    @Override
    public void onCreate() {
        super.onCreate();

    DatabaseHelper databaseHelper = new DatabaseHelper(getApplicationContext()); 
    MySingleton.init(databaseHelper); 

    }
}

And the singleton:

public class MySingleton{

   static MySingleton instance; 
   DatabaseHelper databaseHelper; 

   public static void init(DatabaseHelper databaseHelper){
      instance = new MySingleton(databaseHelper);
   }

}

I receive crashes for my app which clearly show that instance is null sometimes while my app runs. Most weird thing: those crashes only happen on the Samsung Galaxy S5!

My understanding was that

  1. the onCreate() method of my application class was guaranteed to be called when my app is started

  2. the instance on a Singleton could never become null, except for when the app would be completely restarted (in which case it should by recreated by my application class).

What's going on here?

PS: I know that Singletons are kinda frowned upon and extending the application class is also not recommended by everyone, but that's not the point here.

EDIT: Just for clarification, the code works 99% of the time. The question is not asking on how to implement the singleton pattern but rather how the lifecycle of my (or any) app can lead to the instance of a Singleton becoming null when it is created in the application 's onCreate() .

I am using singleton method in my application like my way,This works fine for me

        public class AddEventModel {

            private String event_name;
            private String event_image;
            private static AddEventModel _instance;

        //For Single Ton

        public static AddEventModel get_instance() {
                return _instance;
            }

            public static AddEventModel getInstance() {
                if (_instance == null) {
                    _instance = new AddEventModel();
                }
                return _instance;
            }
         public static void set_instance(AddEventModel _instance) {
                AddEventModel._instance = _instance;
            }

        //Getter setter for model.
            public String getEvent_image() {
                return event_image;
            }

            public void setEvent_image(String event_image) {
                this.event_image = event_image;
            }

            public String getEvent_name() {
                return event_name;
            }

            public void setEvent_name(String event_name) {
                this.event_name = event_name;
            }

To set value in singleton I am doing like below,

        edtEventName.addTextChangedListener(new TextWatcher() {

                    @Override
                    public void onTextChanged(CharSequence s, int start, int before, int count) {
    //Save edit text value in single ton instance.  
                AddEventModel.getInstance().setEvent_name(edtEventName.getText().toString().trim());
                    }

                    @Override
                    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                    }

                    @Override
                    public void afterTextChanged(Editable s) {

                    }
                });

To Get value back from singleton,

     @Override
            public void onResume() {
                super.onResume();

        // Set same value saved in single ton before in onResume. 
        edtEventName.setText(AddEventModel.getInstance().getEvent_name());

        }

Try to use singleton like this way,Hope this will help you.

Use the following code fro your singlton calass..

public class SingletonModel {
 private static SingletonModel instance;
 public DatabaseHelper databaseHelper; 


 public synchronized  static SingletonModel getSingletonModel() {

     if (instance == null) {
         instance = new SingletonModel();
     }
     return instance;

 }

 private void SingletonModel(){}

 }

Please check you manifest file inside application have you put android:name="" like:

<application
        android:name=".application.DoodhwaalaApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

You should have a constructor that accepts DatabaseHelper objects also make instance as static...

public class MySingleton {

    static MySingleton instance;

    DatabaseHelper databaseHelper;

    public/private MySingleton(DatabaseHelper databaseHelper) {
        // TODO Auto-generated constructor stub
    }

    public static void init(DatabaseHelper databaseHelper) {
        instance = new MySingleton(databaseHelper);
    }
}

A singleton should have a private constructor Hence the only fact you can do this

 instance = new MySingleton(databaseHelper);

in different class than MySingleton makes it something different from a Singleton

you should get the only existing instance through a public static method like

 instance = MySingleton.getInstance(databaseHelper);

If you need it, in its implementation be careful to verify there are not possibilities to return null

Another way of creating Singleton class is by declaring private constructor along with class instance as static-final which will create your singleton object at the time of class loading. But make sure your DatabaseHelper object is initialized before MySingleton class is loading into JVM.

Refer below example for more details.

public class MySingleton {

    public static final MySingleton singleton = new MySingleton(DatabaseHelper databaseHelper);
    DatabaseHelper databaseHelper=  null;

    private MySingleton(DatabaseHelper databaseHelper) {
        this.databaseHelper = databaseHelper;
    }

    public MySingleton getInstance() {
        return singleton;
    }
}

您应该陷入多线程问题:在一个线程中,您设置了没有volatile修饰符(或同步部分)的单例,然后在另一个线程中,您看到了过时的值。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM