I am using singleton class in my android app to store the data that is fetch from webserivce.
The problem arrives when, the app goes in background and after few min it come in foreground the application gets Crash because the values stored in singleton class gets null.
I thing the Garbage collection of the phone make the value null.
I had tried this method to solve this issue. But still its coming
private static SingleTon uniqueInstance;
private SingleTon() {
}
public static synchronized SingleTon getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new SingleTon();
}
return uniqueInstance;
}
Any solution for this problem.
Your application may get killed anytime when it is in background to reclaim some resources.
If your application gets killed, then all the static variable will automatically be null again.
If you have some important data to save, save it in a storage option. I suggest you to always access you singleton with SingleTon.getIntance(). This way, if your instance was killed, you can initialize it.
And don't use static methods in a singleton class... that is just pointless.
I started to learn the android framework and my biggest problem is the hell around the activity life cycle. So when the user rotate the screen my application just crash. As I understand beside the normal activity life cycle Android hacked a force-instance-deleter-and-partially-recovery service for me which is not a bug but a feature.
So I just want my member variable keeps safe, so a I thought a start storing it in the Application class.
So I want to refactor my program in the following way:
I create an own Application
public class MainApp extends Application {
LoginActivityData loginActivityData; // create data "segment" for every activity
FirstActivityData firstActivityData;
...
public static MainApp getInstance(final Context context) {
if (context == null) return null;
final Context app = context.getApplicationContext();
return app instanceof MainApp ? (MainApp) app : null;
}
}
In activities and fragments I stop using member variables except the one from the MainApp class.
public class LoginActivity extends Activity {
LoginActivityData loginActivityData;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loginActivityData = MainApp.getInstance(this).loginActivityData;
}
Is there any drawback of this design?
Yes, there is a drawback. Your application object can and will be destroyed by the system when it needs to recover memory, and the application object does not have callback methods that can be used to save state. See here for a fuller explanation.
There are many ways to persist data/state, but if you use the following approach you generally won't go far wrong:
Use onPause() to save long-term data to a SQLite DB/SharedPreferences/cloud etc. Restore it wherever appropriate (onCreate(), onResume(), ...).
Use onSaveInstanceState() to save temporary data to a Bundle. Restore it in onCreate()/onRestoreInstanceState(). The bundle is automatically passed around to the appropriate methods by the system. Note that there is no guarantee that onSaveInstanceState() will be called, so don't use it for critical data.
An extended Application class can declare global variables. Are there other reasons?
Introduction:
If we consider an apk file in our mobile, it is comprised of
multiple useful blocks such as, Activitys, Services and
others.
These components do not communicate with each other regularly and
not forget they have their own life cycle. which indicate that
they may be active at one time and inactive the other moment.
Requirements:
Sometimes we may require a scenario where we need to access a
variable and its states across the entire Application regardless of
the Activity the user is using,
An example is that a user might need to access a variable that holds his
personnel information (e.g. name) that has to be accessed across the
Application,
We can use SQLite but creating a Cursor and closing it again and
again is not good on performance,
We could use Intents to pass the data but it's clumsy and activity
itself may not exist at a certain scenario depending on the memory-availability.
Uses of Application Class:
Access to variables across the Application,
You can use the Application to start certain things like analytics
etc. since the application class is started before Activitys or
Servicess are being run,
There is an overridden method called onConfigurationChanged() that is
triggered when the application configuration is changed (horizontal
to vertical & vice-versa),
There is also an event called onLowMemory() that is triggered when
the Android device is low on memory.
Application class is the object that has the full lifecycle of your application. It is your highest layer as an application. example possible usages:
You can add what you need when the application is started by overriding onCreate in the Application class.
store global variables that jump from Activity to Activity. Like Asynctask.
etc
Sometimes you want to store data, like global variables which need to be accessed from multiple Activities - sometimes everywhere within the application. In this case, the Application object will help you.
For example, if you want to get the basic authentication data for each http request, you can implement the methods for authentication data in the application object.
After this,you can get the username and password in any of the activities like this:
MyApplication mApplication = (MyApplication)getApplicationContext();
String username = mApplication.getUsername();
String password = mApplication.getPassword();
And finally, do remember to use the Application object as a singleton object:
public class MyApplication extends Application {
private static MyApplication singleton;
public MyApplication getInstance(){
return singleton;
}
#Override
public void onCreate() {
super.onCreate();
singleton = this;
}
}
For more information, please Click Application Class
Offhand, I can't think of a real scenario in which extending Application is either preferable to another approach or necessary to accomplish something. If you have an expensive, frequently used object you can initialize it in an IntentService when you detect that the object isn't currently present. Application itself runs on the UI thread, while IntentService runs on its own thread.
I prefer to pass data from Activity to Activity with explicit Intents, or use SharedPreferences. There are also ways to pass data from a Fragment to its parent Activity using interfaces.
The Application class is a singleton that you can access from any activity or anywhere else you have a Context object.
You also get a little bit of lifecycle.
You could use the Application's onCreate method to instantiate expensive, but frequently used objects like an analytics helper. Then you can access and use those objects everywhere.
Best use of application class.
Example: Suppose you need to restart your alarm manager on boot completed.
public class BaseJuiceApplication extends Application implements BootListener {
public static BaseJuiceApplication instance = null;
public static Context getInstance() {
if (null == instance) {
instance = new BaseJuiceApplication();
}
return instance;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onBootCompleted(Context context, Intent intent) {
new PushService().scheduleService(getInstance());
//startToNotify(context);
}
Not an answer but an observation: keep in mind that the data in the extended application object should not be tied to an instance of an activity, as it is possible that you have two instances of the same activity running at the same time (one in the foreground and one not being visible).
For example, you start your activity normally through the launcher, then "minimize" it. You then start another app (ie Tasker) which starts another instance of your activitiy, for example in order to create a shortcut, because your app supports android.intent.action.CREATE_SHORTCUT. If the shortcut is then created and this shortcut-creating invocation of the activity modified the data the application object, then the activity running in the background will start to use this modified application object once it is brought back to the foreground.
I see that this question is missing an answer. I extend Application because I use Bill Pugh Singleton implementation (see reference) and some of my singletons need context. The Application class looks like this:
public class MyApplication extends Application {
private static final String TAG = MyApplication.class.getSimpleName();
private static MyApplication sInstance;
#Contract(pure = true)
#Nullable
public static Context getAppContext() {
return sInstance;
}
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate() called");
sInstance = this;
}
}
And the singletons look like this:
public class DataManager {
private static final String TAG = DataManager.class.getSimpleName();
#Contract(pure = true)
public static DataManager getInstance() {
return InstanceHolder.INSTANCE;
}
private DataManager() {
doStuffRequiringContext(MyApplication.getAppContext());
}
private static final class InstanceHolder {
#SuppressLint("StaticFieldLeak")
private static final DataManager INSTANCE = new DataManager();
}
}
This way I don't need to have a context every time I'm using a singleton and get lazy synchronized initialization with minimal amount of code.
Tip: updating Android Studio singleton template saves a lot of time.
I think you can use the Application class for many things, but they are all tied to your need to do some stuff BEFORE any of your Activities or Services are started.
For instance, in my application I use custom fonts. Instead of calling
Typeface.createFromAsset()
from every Activity to get references for my fonts from the Assets folder (this is bad because it will result in memory leak as you are keeping a reference to assets every time you call that method), I do this from the onCreate() method in my Application class:
private App appInstance;
Typeface quickSandRegular;
...
public void onCreate() {
super.onCreate();
appInstance = this;
quicksandRegular = Typeface.createFromAsset(getApplicationContext().getAssets(),
"fonts/Quicksand-Regular.otf");
...
}
Now, I also have a method defined like this:
public static App getAppInstance() {
return appInstance;
}
and this:
public Typeface getQuickSandRegular() {
return quicksandRegular;
}
So, from anywhere in my application, all I have to do is:
App.getAppInstance().getQuickSandRegular()
Another use for the Application class for me is to check if the device is connected to the Internet BEFORE activities and services that require a connection actually start and take necessary action.
Source: https://github.com/codepath/android_guides/wiki/Understanding-the-Android-Application-Class
In many apps, there's no need to work with an application class directly. However, there are a few acceptable uses of a custom application class:
Specialized tasks that need to run before the creation of your first activity
Global initialization that needs to be shared across all components (crash reporting, persistence)
Static methods for easy access to static immutable data such as a shared network client object
You should never store mutable instance data inside the Application object because if you assume that your data will stay there, your application will inevitably crash at some point with a NullPointerException. The application object is not guaranteed to stay in memory forever, it will get killed. Contrary to popular belief, the app won’t be restarted from scratch. Android will create a new Application object and start the activity where the user was before to give the illusion that the application was never killed in the first place.
To add onto the other answers that state that you might wish store variables in the application scope, for any long-running threads or other objects that need binding to your application where you are NOT using an activity (application is not an activity).. such as not being able to request a binded service.. then binding to the application instance is preferred. The only obvious warning with this approach is that the objects live for as long as the application is alive, so more implicit control over memory is required else you'll encounter memory-related problems like leaks.
Something else you may find useful is that in the order of operations, the application starts first before any activities. In this timeframe, you can prepare any necessary housekeeping that would occur before your first activity if you so desired.
2018-10-19 11:31:55.246 8643-8643/: application created
2018-10-19 11:31:55.630 8643-8643/: activity created
You can access variables to any class without creating objects, if its extended by Application. They can be called globally and their state is maintained till application is not killed.
The use of extending application just make your application sure for any kind of operation that you want throughout your application running period. Now it may be any kind of variables and suppose if you want to fetch some data from server then you can put your asynctask in application so it will fetch each time and continuously, so that you will get a updated data automatically.. Use this link for more knowledge....
http://www.intridea.com/blog/2011/5/24/how-to-use-application-object-of-android
I have many global final constants in my application. I populate these constants from a json file during application startup. As recommended by many people, I am using the application class to keep the global variables in memory. But sometimes, after I close the application and play around with other apps and then come back to my app, it crashes. I understand this is because the system kills the process so these static variables are lost from memory. The recommended solution is to use sharedpreferences or other persistant storage methods to store these global variables. But I need a quick and easy solution to 'fix' this issue. For example, What is the easiest way to force restart the app, if the system kills the process(while the app in running in the background) and user comes back to the app later? I hope my question is clear.
Thanks in advance
Tom
As Kai suggested, i.e.:
public class MyApplication extends Application {
#Override
public void onCreate(){
super.onCreate();
initVariables();
}
}
Or use accessors:
public class MyApplication extends Application {
MyVar var;
public MyVar getVar(){
if(var == null){
initVariables();
}
return var;
}
}
Once your app is being paused (not visible to users), by specification Android system can simply kill the process your app resides in without any additional callback, so what you are trying to do is playing against system behavior.
If you keep those variables in your Application class, then you can simply reload those variables when your Application class is being loaded.
In my Android app I have set a custom Application-derived class. In it I have a member field to store some arbitrary object in.
So I have:
public class MyApp extends Application {
public static MyApp mInstance;
public Object mData;
#Override
public void onCreate() {
mInstance = this;
}
public void setData(Object data) {
mData = data;
}
public Object getData() { return mData; }
}
Now in one Activity I'm doing
public doSetData() {
someMyData = ....
MyApp.mInstance.setData(someMyData);
}
In another Activity I'm doing
#Override
public void onCreate(Bundle) {
Object myDataRetrieved = MyApp.mInstance.getData();
}
I can see that sometimes myDataRetrieved is null. However, I believe I have never passed null in MyApp.setData(). Of course, I can be wrong.
Yet, can there be such circumstances under which MyApp.mData becomes null by itself?
Yet, can there be such circumstances under which MyApp.mData becomes null by itself?
Sure. It will happen every time Android terminates the process, which will happen when your app is not in the foreground, Android needs RAM, and your app is next in line to be terminated.
just save your data and load it up on application object creation if the instance was destroyed, which will always be created before the activity.
if you minimize the memory use then it will survive longer in the android zygote before beig purged. saveinstancestate etc are good only for small data blocks. sharing data through app instance is ok and sometimes recommended, however it is not different from using static fields. same constraints apply.
if you want minimal memory use then using the parcels etc to save your data is not recommended, not even by google.
You can never guarantee that your data will be retained in memory, since the system can always reap the process to reclaim resources.
Thus, your application must always be prepared to save any persistent data either in onSaveInstanceState() (short term) or in onPause() (long term), and then retrieve it in onCreate().
That said, there's also the "singleton pattern" which I'm quite fond of. This is a software design pattern in which you create a special class just to hold your persistent data. There's only ever once instance of the class (thus the name "singleton") which is created on demand the first time your data is needed. The singleton is retained so that any subsequent needs for the persistent data just use the same object without the need to re-load the data from long-term storage. As long as the system doesn't reap your process, the data is always there with nearly zero cost to access. If the system does reap your process, the data is transparently re-loaded, and your application never notices the difference.
See https://stackoverflow.com/a/14779357/338479 for my implementation of a singleton.