There are several activities and fragments that need access to a specific data, so i created a singleton object to store data in that. The problem is after a long time that the app is in background, that singleton object will disapear and become null, so when i open my app again the app crashes and throws null pointer exception to that object. What should I do? How should i share that data between activities and fragments?
Is it a good practice to store that data in database? Or bundle? or whatever?
This is my singleton:
public class Book {
private static Book ourInstance;
private int FLNB;
private Book() {
}
public static Book getInstance() {
if (ourInstance == null) {
ourInstance = new Book();
}
return ourInstance;
}
public void setFLNB(int FLNB) {
this.FLNB = FLNB;
}
public int getFLNB() {
return this.FLNB;
}
}
I set FLNB, and when singleton is gone, the value of FLNB is cleared and I need to access this value after re-initial singleton.
Related
In this Singleton instance, can this private Long severDate become garbage collected when the singleton instance is still not null?
I encountered this is in an Android app. Wondering Android OS somehow freeing unused individual memory values.
public class DataHolder {
private static DataHolder self;
private Long severDate;
private int numb;
public static synchronized DataHolder getInstance() {
if (self == null) {
self = new DataHolder();
}
return self;
}
}
Until "Long severDate" has a references to it, GC wont be deleting it. Now it all depends on the useCase whether u have created the instance of this singleton class in some classes or not.
P.S: In android make sure that u create the obj of this class in onCreate method.
Ok so I'm trying to keep a singleton instance of GetItemQuery which is a POJO to hold the requests and response fields needed for Retrofit API calls. I dont need to create a new GetItemQuery every time I make a call, hence I'm using the singleton pattern to set the fields of the existing GetItemQuery instance.
public class GetItemQuery {
// request data
private String itemId;
private int numberToLoad;
// response data
private Item item;
private static class Loader {
static final GetItemQuery sInstance = new GetItemQuery();
}
public static GetItemQuery getInstance(Item item) {
GetItemQuery instance = Loader.sInstance;
instance.setItem(item);
return instance;
}
public Item getItem() {
if (item == null) {
item = new Item();
}
return item;
}
public void setItem(Item item) {
this.item = item;
}
// other getters and setters
}
in my Android app. At what points should I be worried that getInstance() will be garbage collected so all the fields are cleared? Or is there a way for me to manually garbage collect so I ensure some fields don't become null unexpectedly?
Like described in this answer:
When would the garbage collector erase an instance of an object that uses Singleton pattern?
It will not be garbage collected, because there is a static reference
Currently, I have a class whose constructor takes a username, password, and Context. I would like to be able to access this object from anywhere, so I was thinking of implementing a singleton pattern.
The current constructor uses the credentials passed in to authenticate future api calls through that class. If I were to implement the singleton pattern, my first thought would to be have the getInstace() method take a username, password, etc.., but it seems wrong to have to pass that info everytime i grab an instance. Because of this I was thinking of adding some sort of .authenticate(usr, pswrd) method to be called when grabbing the first instance.
My question is, is this the correct approach? If not, what would be a good way to handle this? Heres the current code:
constructor:
public Play(String username, String password, Context context) {
api = getApi(username, password);
Intent intent = new Intent(context, MyService.class);
context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
//check if first run
//if so, call api for info and store locally
//if not, update as needed
SharedPreferences pref = context.getSharedPreferences("pref", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
if (pref.getBoolean("first_run", true)) {
loadInitialData(context);
}
editor.putBoolean("first_run", false);
editor.commit();
}
Singleton pattern restricts the instantiation of a class and ensures that only one instance of the class exists in the java virtual machine. The singleton class must provide a global access point to get the instance of the class. Singleton pattern is used for logging, drivers objects, caching and thread pool
This code is not tested but should give you an idea how you can use singleton pattern while using SharedPrefrencess.
Constructor is private, So only getInstance() method can access the instance, so you will create an instance of this class if it doesn't exists or if instantiated previously use that instance
synchronization is required to make sure when multiple thread are trying to make a instance for the first time
import android.content.Context;
import android.content.SharedPreferences;
/**
* Created by Pankaj Nimgade on 23-05-2016.
*/
public class Play {
/**
* volatile keyword ensures that multiple threads handle the uniqueInstance
* variable correctly when it is being initialized to Singleton instance
*/
private volatile static Play play;
private static final String XML_FILE = "play_xml_file.xml";
private static final String KEY_DATA = "SOME_DATA_KEY";
private static final String KEY_USERNAME = "SOME_USERNAME_KEY";
private static final String KEY_PASSWORD = "SOME_PASSWORD_KEY";
private static SharedPreferences sharedPreferences;
private static SharedPreferences.Editor editor;
private Play() {
}
public static Play getInstance(Context context) {
if (play == null) {
synchronized (Play.class) {
if (play == null) {
sharedPreferences = context.getSharedPreferences(XML_FILE, Context.MODE_PRIVATE);
editor = sharedPreferences.edit();
play = new Play();
}
}
}
return play;
}
public boolean saveSomeData(String someData) {
editor.putString(KEY_DATA, someData);
return editor.commit();
}
public String readSomeData() {
return sharedPreferences.getString(KEY_DATA, "default Value");
}
public boolean saveUserNameData(String username) {
editor.putString(KEY_USERNAME, username);
return editor.commit();
}
public String readUserNameData() {
return sharedPreferences.getString(KEY_USERNAME, "default username Value");
}
public boolean savePasswordData(String password) {
editor.putString(KEY_PASSWORD, password);
return editor.commit();
}
public String readPasswordData() {
return sharedPreferences.getString(KEY_PASSWORD, "default password value");
}
}
in this above approach I am making instance creation of the class lazy, as the instance will only be created if demanded, although the code is thread safe and will work on all Java version you may want to consider different approach to implement this if you are using Java 5 and above.
https://sourcemaking.com/design_patterns/singleton/java/1
public class Singleton {
// Private constructor prevents instantiation from other classes
private Singleton() {}
/**
* SingletonHolder is loaded on the first execution of Singleton.getInstance()
* or the first access to SingletonHolder.INSTANCE, not before.
*/
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
The inner class is referenced no earlier (and therefore loaded no earlier by the class loader) than the moment that getInstance() is called. Thus, this solution is thread-safe without requiring special language constructs (i.e. volatile or synchronized).
I read a lot but couldn't understand how to restore state when some data kept on singletone class. for example
public class UserDataKeeper {
private static UserDataKeeper instance;
private User mUser;
private UserDataKeeper(){
}
public static UserDataKeeper getInstance() {
if (instance == null) {
instance = new UserDataKeeper();
}
return instance;
}
public User getUser() {
return mUser;
}
public void setUser(User mUser) {
this.mUser = mUser;
}
}
When my android application come from background user data becoming null. what should I do here for not getting null result.
Is the only solution is save data using SQLite,Preference or something else ?
Even if you're implementing a Singleton (which is almost always a bad solution), you're still storing the data in memory. After your application is closed the data will be lost. If you want persistent storage then yes, you'll need to have either a SQLite database, or write your information to disk.
I'm working in a application which has many activities and most of the activities share more than one objects, So I created MyApplication class by extending android Application class to store selected objects to share. But I feel quit uncomfortable while accessing those objects inside provider/helper classes b'coz context is needed in providers to get instance of Application.
So I planned to create static class called SelectionProvider inside MyApplication class to store selected objects, then I can access those in static way without create instance to MyApplication.
MyApplication class with static inner class as follows
class MyApplication extends Application {
public static final String TAG = "MyApplication";
public static class SelectionProvider {
private static UserObj userObj;
private static TownObj townObj;
private static StoreObj storeObj;
public static UserObj getUserObj() {
return userObj;
}
public static setUserObj(UserObj userObj) {
this.userObj = userObj;
}
public static TownObj getTownObj() {
return townObj;
}
public static setTownObj(TownObj townObj) {
this.townObj = townObj;
}
public static StoreObj getStoreObj() {
return storeObj;
}
public static setStoreObj() {
this.storeObj = storeObj;
}
}
}
Is it right approach? if not why?
Will reside the selected objects (which are stored in inner class) in entire application life or will it destroyed anywhere?
This method or a static value elsewhere should work fine and last for the lifetime of the application as long as you don't have multiple processes running that need access to this object. If that's the case, you should use a Service to handle transactions.
I would not design it as an inner class. I would create SelectionProvider (and any other classes you need) as its own separate class, and instantiate it in your MyApplication class' onCreate method.
You should not instantiate the application object as it can be accessed at any time by calling getApplication() and casting it to your application class (e.g. (MyApplication)getApplication(); Then you can access any objects created by the class.
If data persistence is an issue with these classes, consider storing their values in SQLLite or as a Shared Preference, as Android may terminate your application at any time when it is in the background if it needs the resources.
I would create a singleton class of my own:
public class Data {
/* Start of singleton block */
private static Data data = new Data();
private Data(){
}
public static Data getInstance(){
}
/* End of singleton block */
private SelectionProvider selectionProvider;
public SelectionProvider getSelectionProvider(){
return selectionProvider;
}
/* other necessary methods (get, set) and classes below */
}
This way you can access your objects with Data.getInstance().getSelectionProvider().
This will be available during an active application, though you might want to build in some persistant storing of your data for when the user leaves the app for some time to come back later:
public SelectionProvider getSelectionProvider(){
if(selectionProvider == null)
selectionProvider = readSelectionProviderFromPersistantStorage();
return selectionProvider;
}