Crash with Singleton Class - android

I launched my first Android application last week. Some crashes have been reported in Google Dev Console.
Of them is a java.lang.RuntimeException caused by a java.lang.NullPointerException on the following line:
mNoJokersGameVersion = GameData.getInstance().ismNoJokersGameVersion();
The class GameData is implemented as a Singleton:
public class GameData {
private Boolean mNoJokersGameVersion;
private static GameData mInstance = null;
//Constructor is private because GameData class is a singleton
private GameData() {
mNoJokersGameVersion = null;
}
//(Only) This function gives access to the singleton GameData
public static GameData getInstance() {
if (mInstance == null) {
mInstance = new GameData();
}
return mInstance;
}
public Boolean ismNoJokersGameVersion() {
return mNoJokersGameVersion;
}
public void setmNoJokersGameVersion(Boolean mNoJokersGameVersion) {
if (this.mNoJokersGameVersion != null) {
throw new IllegalStateException("mNoJokersGameVersion was already set");
}
this.mNoJokersGameVersion = mNoJokersGameVersion;
}
}
On the creation of the first Activity, setmNoJokersGameVersion is called with the value read from a .xml configuration file:
Boolean jokers_version_off = Integer.valueOf(getValue("jokers", element2)) == 0;
GameData.getInstance().setmNoJokersGameVersion(jokers_version_off);
What could go wrong ?
Important note: the crash happened a few times, not always. Is the Garbage Collector responsible for that?
Is switching from Boolean to boolean inside the class GameData a possible fix ?

The NullPointerException is referring to your Boolean and not the singleton instance. You set the initial value of the boolean to null, so what is probably happening is your GameData got created but the boolean didn't get set yet. Changing to the primitive type boolean with a default value should fix this.
A possible scenario that might lead to this is for instance an orientation change. This will delete nullify the GameData object forcing it to be recreated (when calling getInstance()). But the Boolean might not be set the next time you access it.

Related

What happens if I close my android application without closing an open realm instance?

I have kept a single realm instance opened on main thread in Application class and I use that single instance to do all kinds of DB operations from MainActivity. Since my application has a single activity, I close the instance in the activity's onDestroy(). The app is working fine for me as of now.
What are the repercussions of not doing a realm.close()? My database hasn't corrupted with or without the same.
Also, I've read that there are scenarios in which the Activity's onDestroy() may not get called at all. What effects the database can have in such a scenario if closing realm is so important?
public class MyApp extends Application {
private static MyApp instance;
private Realm realm;
public void onCreate() {
super.onCreate();
Realm.init(this);
Realm.setDefaultConfiguration(new RealmConfiguration.Builder()
.schemaVersion(BuildConfig.VERSION_CODE)
.migration(new RealmMigrationClass())
.compactOnLaunch()
.build());
realm = Realm.getInstance(Realm.getDefaultConfiguration());
}
public static MyApp getInstance() {
return instance;
}
public Realm getRealm() {
return realm;
}
}
MainActivity
public class MainActivity extends Activity {
#Override
protected void onDestroy() {
MyApp.getInstance().getRealm().close();
super.onDestroy();
}
}
Closing the realm instance is very important because of realm core has been written in c++ programming language and is compiled in the native code.And we know the c++ garbage collection does not run automatically we require to manually call the garbage collection.So when you call the realm.close() it means that realm deallocation the native memory means free or delete the pointer variable and also do the file descriptor job.From realm.close() means you give the command or tell to native c++ compiler to run the garbage collection.
If you look the "doc" (REALM_DOC) for Realm for Java you can find:
Realm implements Closeable to take care of native memory deallocation
and file descriptors, so always close your Realm instances when you’re
done with them.
Realm instances are reference counted—if you call getInstance twice in
a thread, you need to call close twice as well. This allows you to
implement Runnable classes without having to worry about which thread
will execute them: simply start it with getInstance and end it with
close.
Personally I suggest you to define a class in which define your Realm functions and an "Realm attribute" (like a "RealmHelper" class) then inside this class define:
- a unstatic Realm
- a static RealmHelper instance
You will always use this RealmHelper static instance for all operations in your Realm inside your main Thread, inside other threads you will call "new RealmHelper()" and CLOSE the realm just after you did the operation.
Doing this in your MainThread you just need to close ONE realm instance when the application get closed, to do this you can use the "Application.ActivityLifecycleCallbacks" interface inside a Custom defined Application class (so which extends Application of Android).
Example inside you Application custom class:
/* START Override ActivityLifecycleCallbacks Methods */
#Override
public void onActivityCreated(Activity activity, Bundle bundle) {
}
#Override
public void onActivityStarted(Activity activity) {
// Check if your MyRealmClass instance is null or is closed, in this case
// re-initialize it.
if(MyRealmClass.getInstance() == null || MyRealmClass.getInstance().getRealm().isClosed()){
MyRealmClass.initInstance();
}
}
#Override
public void onActivityResumed(Activity activity) {
}
#Override
public void onActivityPaused(Activity activity) {
}
#Override
public void onActivityStopped(Activity activity) {
if(!AppUtils.isAppOnForeground(this)){
// Close your MyRealmClass instance
if(MyRealmClass.getInstance() != null) {
MyRealmClass.getInstance().close();
MyRealmClass.getInstance().logRealmInstanceCount(LABEL_APP_IN_BACKGROUND);
MyRealmClass.setMyInstance(null);
}
}
}
#Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
}
#Override
public void onActivityDestroyed(Activity activity) {
}
/* END Override ActivityLifecycleCallbacks Methods */
Code of "isAppOnForeground" (check if your app is in foreground, if is not this mean your app is being closed):
public static boolean isAppOnForeground(Context context) {
boolean ret = false;
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
if(appProcesses != null){
String packageName = context.getPackageName();
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
ret = true;
}
}
}
return ret;
}
Your "MyRealmClass" will look like:
public class MyRealmClass {
protected Realm mRealm;
protected static MyRealmClass mInstance;
public MyRealmClass() {
mRealm = Realm.getDefaultInstance();
}
public static MyRealmClass initInstance(){
if(mInstance == null){
mInstance = new MyRealmClass();
}
return mInstance;
}
public static MyRealmClass getInstance(){
return mInstance;
}
public static void setMyInstance(MyRealmClass instance) {
mInstance = instance;
}
public Realm getRealm() {
return mRealm;
}
public void setRealm(Realm realm){
this.mRealm = realm;
}
public void close() {
if (mRealm != null) {
try {
mRealm.close();
} catch(Exception e){
onException(e);
}
}
}
[...]
Then you need to check that all your Realm instance is not closed when you use a RealmObject or you do some operation in your Realm. And if it is closed (because the app got in background and then restarted) you need to re-initialize the realm (if you have an activity with a MyRealmClass instance as attribute).
Example in a BaseMyActivity:
public abstract class MyBaseActivity extends AppCompatActivity {
protected MyRealmClass mRealmClass;
/* START Override Lifecycle Methods */
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initMyRealmClass();
Lyra.instance().restoreState(this, savedInstanceState);
}
#Override
protected void onStart() {
super.onStart();
initMyRealmClass();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Lyra.instance().saveState(this, outState);
}
/* END Override Lifecycle Methods */
/* START Private Methods */
protected void initMyRealmClass(){
if(mRealmClass == null || mRealmClass.getRealm().isClosed()){
mRealmClass = MyRealmClass.initInstance();
}
}
/* END Private Methods */
}
Basically all your activities will extend this BaseActivity if they need to use Realm functions. (Lyra is used to save the state of any of your attributes: LYRA)
REMEMBER THAT:
if you set or get some attributes from a RealmObject or you get an object from a RealmList or RealmResults you NEED THAT YOUR REALM INSTANCE, from which the object was take, IS OPEN.
OTHERWISE you need to use this method when you init a variable with objects from the realm: (this methods should be placed in yuour "MyRealmClass")
public <T extends RealmObject> List<T> toList(RealmResults<T> results) {
return mRealm.copyFromRealm(results);
}
public <T extends RealmObject> List<T> toList(RealmList<T> results) {
return mRealm.copyFromRealm(results);
}
public <T extends RealmObject> T copyObjectFromRealm(T obj) {
return mRealm.copyFromRealm(obj);
}
public <T extends RealmObject> RealmResults<T> findAllObject(Class<T> classObject) {
RealmQuery<T> query = mRealm.where(classObject);
return query.findAll();
}
Now if you need to get a List of "MyRealmObjectClass" objects and add them to an adapter you will do this:
List<MyRealmObjectClass> myObjects = mRealmClass.toList(mRealmClass.findAllObject(MyRealmObjectClass.class))
myAdapter.addAll(myObjects);
Doing this if you "get" or "set" an attribute after the Realm instance, from which you got the objects, was closed (for example after the app get to background and then restarted) you won't get an exception.
BUT if you "set" an attribute of your RealmObject this WON'T BE SET in the REALM INSTANCE, so to change the value of a RealmObject inside the Realm in this case you need to Save the object!
OTHERWISE if you have a RealmResults or a RealmObject which is still connected to the Realm, so you can directly change, inside a transaction, an attribute of it and it will be changed inside the Realm too.
To do a Realm Transaction I suggest you to follow the DOC in the first link and, if you don't need to close the Realm in the Finally block, enable lambda and do this:
mRealm.executeTransaction(
realm -> {
[do your Realm operations]
}
)
or you can also do:
public boolean doRealmOperation(Object... params){
AtomicBoolean ret = new AtomicBoolean(false);
mRealm.executeTransaction(
realm -> {
try{
[do your realm operation]
ret.set(true);
} catch(Exception e){
onException(e)
ret.set(false);
}
}
)
}
in this case you need to use the "AtomicBoolean" because you will set the value you want to return inside the transaction, but inside a transaction the value got from outside of the transaction itself (in this case the "ret" variable) MUST BE A FINAL variable. But you can't define "ret" as "final" and then set it again, so you need to use the "AtomicBoolean" to set the variable outside the transaction and set it again inside the transaction itself.
(You can also avoid this problem by using a temporary variable to get the "true/false" value inside the transaction and then set the "ret" variable using that "temp variable". But personally I prefer to use "AtomicBoolean" class which is, I think, safer and more clean than a temp variable)
Hope this is helpful,
see you by and happy coding! ;)
Realm implements Closeable to take care of native memory deallocation and file descriptors, so always close your Realm instances when you’re done with them.
Realm instances are reference counted—if you call getInstance twice in a thread, you need to call close twice as well.
From my personal experience not closing realm has not caused a lot of issues, in fact when I tried closing it at times it would cause an issue when the app went into the background and was then resumed which caused a crash due to realm instance being closed, I am not sure why a new instance of realm was not created in that case, might have been a bug.
As of now I follow the realm docs and close my realm instances until they cause an issue.
General coding practises suggest that anything that is opened should be safely closed.
Yes, it will get closed only if you called close() method on your application's destroy() method. Remember Realm implements Closeable in order to take care of native memory deallocation and file descriptors so it is important to close your Realm instances when you are done with them.
For further info visit this link.

Object sharing between multiple activities

I wanted to share an object(has multiple states) between 3 activities and any of the activities can modify the object state and the same state should be accessible to all 3 activities.
I do not want to use singleton object as it will exist for whole application.
Shared object should only persist till the time these 3 activities are present.
hi #rahul you can implement parcelable in your object and pass it via Intent to all activities.In this way you can maintain states as well as avoid singleton.
Since making a object parcelable involves more boilerplate code you can use this parceler library which needs no boilerplate code.
After making a object parcelable you can pass that to any activity via Intent like this
Intent intent = new Intent(this, MyActivity.class);
intent.putParcelable("key", object_you_want_to_pass);
...
startActivity(intent);
If your object can be serialized, maybe you could try to use SharedPreferences to store your specific object, using one of the methods described here. You can then parse it and modify it from any activity.
And if you want it to be persistent only when all of your three activities are running, just clear your SharedPreferences entry.
In general designing your app you should avoid creating such shared states when it's possible. But if you really need it - see below.
You could create a singleton with kind of "reference counting" - Self releasing (reference counting) singelton
If you want to limit its visibility you can make it package private for instance (if your Activities are in the same package).
But this whole thing looks a bit overcomplicated to me, I'd probably go with normal singleton or a field in your Application class, maybe removing it manually if I know at some time that it's no longer needed.
Singleton is still the best way to manage this.
class Singleton {
static private Singleton _instance = null;
static private boolean _activity1 = false;
static private boolean _activity2 = false;
static private boolean _activity3 = false;
static public register(Activity activity) {
_instance = null;
if (activity instanceOf Activity1) _activity1 = true;
if (activity instanceOf Activity2) _activity2 = true;
if (activity instanceOf Activity3) _activity3 = true;
}
static public unregister(Activity activity) {
_instance = null;
if (activity instanceOf Activity1) _activity1 = false;
if (activity instanceOf Activity2) _activity2 = false;
if (activity instanceOf Activity3) _activity3 = false;
}
static public Singleton getInstance() {
if (_activity1 && _activitiy2 && _activity3) {
if (_instance == null)
_instance = new Singleton();
return _instance;
}
return null;
}
}
class Activity1 {
#Overrride
public void onCreateView() {
Singleton.register(this);
}
#Override
public void onDestroy() {
Singleton.unregister(this);
}
Apply same to Activity2 and 3. Above are only pseudo codes.

Singleton Destruction, Class Loading etc in android

I want to get clarity on loading of classes, destruction of objects etc in android because I noticed some weird things happening when using Singleton in My Activity. Best I will describe it using code :
My Singleton class
public class FilterCriteria {
private final String TAG=FilterCriteria.class.getSimpleName();
private static FilterCriteria filterCriteria=new FilterCriteria();
private FilterCriteria()
{
}
public static FilterCriteria getInstance()
{
return filterCriteria;
}
private int rentUpperBound,rentLowerBound;
private int bedrooms,baths;
private float distance;
private ObjectStateListener listener;
public void setFilters(float distance,int baths,int bedrooms,int rentLowerBound,int rentUpperBound) {
this.distance = distance;
this.baths=baths;
this.bedrooms=bedrooms;
this.rentLowerBound=rentLowerBound;
this.rentUpperBound=rentUpperBound;
if(listener!=null)
listener.onObjectStateChanged();
}
public void attachListener(ObjectStateListener listener) {
if (this.listener == null) {
this.listener = listener;
Log.v(TAG, "NO LISTENER PRESENT AS EXPECTED");
} else {
Log.v(TAG, "LISTENER PRESENT!!! BUT THE ACTIVITY WAS STARTED JUST NOW.");
}
}
public void destroy()
{
filterCriteria=null;
}
}
The attachListener(ObjectStateListener listener) function is called only once in the activity. So, when I open my activity the first time, I get this log from attachListener function
NO LISTENER PRESENT AS EXPECTED
Now, I close the activity and then reopen it. But now I get this log
"LISTENER PRESENT!!! BUT THE ACTIVITY WAS STARTED JUST NOW."
So, that means the object still lives on even after the activity (and the application) was closed. Is this normal???
So, I tried to destroy the singleton instance using the destroy() function in the onDestroy() function of Activity.
#Override
protected void onDestroy(){
filterCriteria.destroy();//Trying to destroy the singleton
super.onDestroy();
Log.v(TAG,"Destroying activity");
}
But I got NullPointerException on this line filterCriteria.destroy(). So, that means android has already made object null, whereas when I see in debug mode, other members of the Activity are still alive. Why is only this null?
What is happening!???
When you invoke the method attachListener() you are creating a reference to the linked object (even if it is static): this reference will be binded to the activity lifecycle.
On the other hand, filterCriteria will follow the static field Java-like lifecycle (but you can still remove this reference manually).

Singleton in Android

I have followed this link and successfully made singleton class in Android.
http://www.devahead.com/blog/2011/06/extending-the-android-application-class-and-dealing-with-singleton/
Problem is that i want a single object. like i have Activity A and Activity B. In Activity A I access the object from Singleton class. I use the object and made some changes to it.
When I move to Activity B and access the object from Singleton Class it gave me the initialized object and does not keep the changes which i have made in Activity A.
Is there any other way to save the changing?
Please help me Experts.
This is MainActivity
public class MainActivity extends Activity {
protected MyApplication app;
private OnClickListener btn2=new OnClickListener() {
#Override
public void onClick(View arg0) {
Intent intent=new Intent(MainActivity.this,NextActivity.class);
startActivity(intent);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Get the application instance
app = (MyApplication)getApplication();
// Call a custom application method
app.customAppMethod();
// Call a custom method in MySingleton
Singleton.getInstance().customSingletonMethod();
Singleton.getInstance();
// Read the value of a variable in MySingleton
String singletonVar = Singleton.customVar;
Log.d("Test",singletonVar);
singletonVar="World";
Log.d("Test",singletonVar);
Button btn=(Button)findViewById(R.id.button1);
btn.setOnClickListener(btn2);
}
}
This is NextActivity
public class NextActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_next);
String singletonVar = Singleton.customVar;
Log.d("Test",singletonVar);
}
}
Singleton Class
public class Singleton
{
private static Singleton instance;
public static String customVar="Hello";
public static void initInstance()
{
if (instance == null)
{
// Create the instance
instance = new Singleton();
}
}
public static Singleton getInstance()
{
// Return the instance
return instance;
}
private Singleton()
{
// Constructor hidden because this is a singleton
}
public void customSingletonMethod()
{
// Custom method
}
}
and MyApplication
public class MyApplication extends Application
{
#Override
public void onCreate()
{
super.onCreate();
// Initialize the singletons so their instances
// are bound to the application process.
initSingletons();
}
protected void initSingletons()
{
// Initialize the instance of MySingleton
Singleton.initInstance();
}
public void customAppMethod()
{
// Custom application method
}
}
When i run this code, i get Hello which i have initialized in Singleton then World which i gave it in MainActivity and again shows Hello in NextActivity in logcat.
I want it to show world again in NextActivity.
Please help me to correct this.
Tip: To create singleton class In Android Studio, right click in your project and open menu:
New -> Java Class -> Choose Singleton from dropdown menu
EDIT :
The implementation of a Singleton in Android is not "safe" (see here) and you should use a library dedicated to this kind of pattern like Dagger or other DI library to manage the lifecycle and the injection.
Could you post an example from your code ?
Take a look at this gist : https://gist.github.com/Akayh/5566992
it works but it was done very quickly :
MyActivity : set the singleton for the first time + initialize mString attribute ("Hello") in private constructor and show the value ("Hello")
Set new value to mString : "Singleton"
Launch activityB and show the mString value. "Singleton" appears...
It is simple, as a java, Android also supporting singleton. -
Singleton is a part of Gang of Four design pattern and it is categorized under creational design patterns.
-> Static member : This contains the instance of the singleton class.
-> Private constructor : This will prevent anybody else to instantiate the Singleton class.
-> Static public method : This provides the global point of access to the Singleton object and returns the instance to the client calling class.
create private instance
create private constructor
use getInstance() of Singleton class
public class Logger{
private static Logger objLogger;
private Logger(){
//ToDo here
}
public static Logger getInstance()
{
if (objLogger == null)
{
objLogger = new Logger();
}
return objLogger;
}
}
while use singleton -
Logger.getInstance();
answer suggested by rakesh is great but still with some discription
Singleton in Android is the same as Singleton in Java:
The Singleton design pattern addresses all of these concerns. With the Singleton design pattern you can:
1) Ensure that only one instance of a class is created
2) Provide a global point of access to the object
3) Allow multiple instances in the future without affecting a
singleton class's clients
A basic Singleton class example:
public class MySingleton
{
private static MySingleton _instance;
private MySingleton()
{
}
public static MySingleton getInstance()
{
if (_instance == null)
{
_instance = new MySingleton();
}
return _instance;
}
}
As #Lazy stated in this answer, you can create a singleton from a template in Android Studio. It is worth noting that there is no need to check if the instance is null because the static ourInstance variable is initialized first. As a result, the singleton class implementation created by Android Studio is as simple as following code:
public class MySingleton {
private static MySingleton ourInstance = new MySingleton();
public static MySingleton getInstance() {
return ourInstance;
}
private MySingleton() {
}
}
You are copying singleton's customVar into a singletonVar variable and changing that variable does not affect the original value in singleton.
// This does not update singleton variable
// It just assigns value of your local variable
Log.d("Test",singletonVar);
singletonVar="World";
Log.d("Test",singletonVar);
// This actually assigns value of variable in singleton
Singleton.customVar = singletonVar;
I put my version of Singleton below:
public class SingletonDemo {
private static SingletonDemo instance = null;
private static Context context;
/**
* To initialize the class. It must be called before call the method getInstance()
* #param ctx The Context used
*/
public static void initialize(Context ctx) {
context = ctx;
}
/**
* Check if the class has been initialized
* #return true if the class has been initialized
* false Otherwise
*/
public static boolean hasBeenInitialized() {
return context != null;
}
/**
* The private constructor. Here you can use the context to initialize your variables.
*/
private SingletonDemo() {
// Use context to initialize the variables.
}
/**
* The main method used to get the instance
*/
public static synchronized SingletonDemo getInstance() {
if (context == null) {
throw new IllegalArgumentException("Impossible to get the instance. This class must be initialized before");
}
if (instance == null) {
instance = new SingletonDemo();
}
return instance;
}
#Override
protected Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException("Clone is not allowed.");
}
}
Note that the method initialize could be called in the main class(Splash) and the method getInstance could be called from other classes. This will fix the problem when the caller class requires the singleton but it does not have the context.
Finally the method hasBeenInitialized is uses to check if the class has been initialized. This will avoid that different instances have different contexts.
The most clean and modern way to use singletons in Android is just to use the Dependency Injection framework called Dagger 2. Here you have an explanation of possible scopes you can use. Singleton is one of these scopes. Dependency Injection is not that easy but you shall invest a bit of your time to understand it. It also makes testing easier.

Store Objects in ApplicationContext

When my application goes to background , my (static and singleton) objects are cleared.
So I tried to store these objects in Applicaton Context . I am using the following code.
Accounts.create(getApplicationContext()) will be called once to store the accounts instance.
Is that possible(reliable) to store objects in Application Context ? I am not sure the following way is correct or not . please guide ..
public class Init extends Application {
private Hashtable<Object, Object> globalStore = new Hashtable<Object, Object>();
public void putToGlobalStore(Object key, Object value) {
globalStore.put(key, value);
}
public Object takeFromGlobalStore(Object key) {
return this.globalStore.get(key);
}
public void removeFromGlobalStore(Object key) {
this.globalStore.remove(key);
}
public boolean containsInGlobalStore(Object key) {
return this.globalStore.containsKey(key);
}
}
public class Accounts {
protected Accounts(String name, Context context) {
Init init = (Init) applicationContext;
init.putToGlobalStore(name, this);
}
private static Init applicationContext;
public static void create(Context context) {
if (context instanceof Application)
applicationContext = (Init) context;
else
applicationContext = (Init) context.getApplicationContext();
if (applicationContext.containsInGlobalStore(GLOBAL_NAME))
Logger.log("Warning " + GLOBAL_NAME
+ " is already created. This will remove all old datas");
new Accounts(GLOBAL_NAME, applicationContext);
}
private static final String GLOBAL_NAME = "accounts";
public static Accounts getInstance() {
try {
return (Accounts) applicationContext
.takeFromGlobalStore(GLOBAL_NAME);
} catch (Exception e) {
Logger.log("GLOBAL_NAME Lost");
return null;
}
}
Please help.
You should know that the application context itself gets destroyed if left unused for a long time in the background. So there is no guarantee that your static and singleton objects will not be cleared when the app is in background. Instead what you can do is persist your objects from time to time (either in a flat-file or shared preference or database) and restore them in the onCreate method of the Application class
I have been using this method in my application and i didn't see any problem unless my process gets killed by the OS or if there is a crash in my application and my app gets restarted.
If you think whatever data you are storing is valid for only life time of a program why don't you override OnCreate of Application object and create all your singletons there. This way you can always make sure your application has all singletons before your app starts functioning.
Application class is not permanent.
If App process killed, Application class private member variable data loss.
Using Shared Preferences.
I know this question was asked a long time ago, but here's a good article that suggests using the Application object to store data is generally not a sound design methodology.

Categories

Resources