What exactly is the purpose of Application class.
what are the benefits of extending it to a custom subclass
Why use it ?
Can global variables be stored in any other class achieve same goal as Application ?
Nice question !
Your application is a context that is always running while your activities and services are running.
It is also the first context to be created and the last to be destroyed.
Thus, it surrounds the life cycle of your app.
You can use the application class as a way to share data or components (for dependency injection for instance). For instance if you want to share a singleton between activities, you can create the instance in the application class and provide a getter, then all other contexts can get the singleton via
((cast to your class)getApplicationContext()).getFoo();
There may be some use cases where you need to do stuff before even your first activity is launched, then do it in the onCreate method of the application class.
On the other hand, you should never relie on the onDestroy method of the Application class, as it is not always called. There is no contract for that on Android.
But this is rare and, usually, you don't need to override the application class though. Dependency injection can be achieved in other ways by RoboGuice or Dagger for instance.
Two things makes this Class very useful:
Application class is instantiated before any other Activity.
It holds the Application Context
Context brings a host of resources for us: we can figure out some device properties, load some resources, initiate a SQLite database etc, etc.
All of this happens before any Activity loads, and all of this is globally available to the Activities.
Simple example of what I mean:
public class App extends Application{
private static Resources sResources;
//--I want to load strings resources from anywhere--
public static String loadStringResource(int resID) {
return sResources.getString(resID);
}
#Override
public void onCreate() {
super.onCreate();
sResources = getResources();
//---I want to load all preferences when my app starts---
PreferenceManager.setDefaultValues(this,R.xml.prefs,false);
}
}
Extending the Application class allows you to integrate into the application's lifecycle.
This is also useful to store global application-level information (though it's usually good to keep your activities 'independent')
The Application class is aware of the Application Context and is loaded when your app is loaded so it holds the proper callbacks for the application lifecycle before your activity starts. You most likely would not want to extend this class.
From the API docs:
There is normally no need to subclass Application. In most situation, static singletons can provide the same functionality in a more modular way. If your singleton needs a global context (for example to register broadcast receivers), the function to retrieve it can be given a Context which internally uses Context.getApplicationContext() when first constructing the singleton.
http://developer.android.com/reference/android/app/Application.html
Related
I'd like to put my database connection object to Application class. I read some tutorials and everywhere I see explicit implementation of a singleton pattern. Something like this
public class MyApplication extends Application {
private static MyApplication singleton;
public static MyApplication getInstance(){
return singleton;
}
#Override
public void onCreate() {
super.onCreate();
singleton = this;
}
}
My question is why do I need to do this explicit implementation? Nobody explains.
I'd like to add there some property, initialized in onCreate() and get it's value in activity.
myProp = (MyApplication)getApplicationContext().getMyProperty()
Is it really necessary to implement singleton pattern?
An Application class is an access point to application context and generally it is used as a initializator for all application-scoped dependencies like your database object. This class is initialized only once per application and persists in memory until application is no longer in memory. So it is a natively created singleton.
By having such static access point to application you may have access to the application context in any class and in general case this context is much better for retrieving resources, system services etc. when you need such dependencies in your custom classes, because it doesn't hold a link to the activity and view so is a leak-safe. Of course in your example the Activity has an access to application, but you have to cast context anyway and better use same approach for a whole app.
Despite you may use it like a global access point to all application scoped and initialized dependencies, do not overload it with huge initialization logic, better create some other singletons for this purpose and just initialize it from Application class. In a big project consider using DI framework, Dagger the best one, for providing dependencies.
By default the application class is singleton..You are not have allowed to create application yourself.Android System will create this when the first time app is loaded into the memory.You are using singleton pattern here just to get Application object from anywhere within the application
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 an android application with a number of activities.
I have a singleton class holding my main data model which all activities access to get data.
The problem is that sometimes the android GC decides to destroy my singleton when the app in the background (when you press the home button).
Is there anyway that I can bypass this?
I've had this exact problem in a current application of mine, which needs to retain a large amount of data in various 'singleton' classes. The problem I encountered was as in your case; i.e. sometimes when bringing the application back to the foreground, some of the static 'singleton' classes have been destroyed.
The problem, I believe, is that the 'lifetime' of such classes can never be well defined or predicted. After all, it's a class sat there holding a reference to itself, so it's susceptible to being garbage collected when the system wants to grab some resources.
You're probably already aware that extending android.app.Application is a well-known alternative to using conventional Singletons. The solution that worked for me is to hold the actual instances of data singleton classes within an extension class of android.app.Application, whose lifecycle is well defined. Any other class that wants to access those singletons can obtain them using a getter in the Application class.
So for example I have a class called AppState that extends Application, that holds the instances within:
import android.app.Application;
public class AppState extends Application {
...
// "Singleton" instances that this Application extension looks after
private MSData singletonInstanceMSData;
public AppState() {
...
singletonInstanceMSData = new MSData();
...
// ---------------- Singleton instance control ----------------
public MSData getMSData(){
return singletonInstanceMSData;
}
// I also provide the means to 'reset' the instances on startup (this is
// something I need to do for my application - you may or may not need to)
public void resetControllerSpecificData(){
singletonInstanceMSData.reset();
...
Don't forget you'll need to modify your manifest if you extend Application.
AFAIR, lifespan os singleton is lifespan of his classloader - also complete VM . When user hit home button, your application goes in backgorund and is probably destroyed - you can not do anything against it. Your best bet is to save whatever is necessary in your onPause() callback ( or just use write through in every change of datza if you really paranoid )
A few days ago I've discovered that singleton can become anti-pattern in Android. My singleton (class with private constructor and instance stored in static field) was deleted (instance was deleted despite the fact other activities were still using this singleton (via getInstance() method) so another instance had to be created ) because Activity from which it was first invoked was deleted (after invoking finish for only this one activity).
I've read already how this problem can be resolved however I've also just read "Effective Java". There is said that "Single-element enum type is the bast way to implement a singleton".
So now I'm wondering what would be the lifecycle of singleton created this way in Android application? Would it be the same like in case of "standard singleton implementation" so after destroying activity from which it was invoked the first time it will be destroyed (even if it used also in other activities)?
I'm not asking about proper android singleton implemenation or the singleton pattern itself (is it pattern or anti-pattern etc) but I'd like to know what be the lifecycle of such enum singleton object and when it will be destroyed.
In all cases, the classes you use are tied to the ClassLoader that loaded them. This is true in Java in general, not just Android. Android will isolate activities by using new ClassLoaders each time -- at the least, it doesn't promise it won't, and it does as far as I can tell.
Any singleton, or other class-level state, is tied to the Class which is tied to the ClassLoader. This is why your state "disappears"; it's actually that your calling code is seeing a new Class in a new ClassLoader.
So, your enum-based trick, or anything else along these lines, would have exactly the same behavior. You just can't "persist" activity information this way. You can and should write to a SQLite DB. You could probably stash it in the SharedPreferences too.
The application object is a good location to store information which needs to be accessible to various activity or service instances. You can retrieve it like this (where this is an Activity or Service):
private MyApplication app;
in onCreate(...){
...
this.app = (MyApplication) this.getApplication();
...
}
Remember to set the name also in the manifest:
Set the attribute "name" of the "application" tag:
The value is the path to the class relative to the package of your app.
The application object is created when the app is started, you can initialize like in an activity or service in it's onCreate() method.
One thing to remember: The application object can survive closing your "last" activity. In this case you may get the same application object with the state from the previous interaction with your app. If this is a problem you must somehow detect the initial start of your app (e.g. using a special launcher activity without UI, which initializes the application object and then starts a new intent.
BTW, the same may happen with singletons if they have not yet been lost to garbage collection.
My secure singleton implementation is like that:
I create a singleton class which has an attribute of boolean 'didReceiveMemoryWarning';
public class SingleTon(){
public boolean didReceiveMemoryWarning = true;
...
...
}
In application first screen(It is exactly first launch screen)(I have a splash screen that is visible 3 sec)
SingleTon.getInstance().didReceiveMemoryWarning = false;
And in every Activity's onCreate() method, check this boolean data,
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(SingleTon.getInstance().didReceiveMemoryWarning){
{ Load your data from local to your SingleTon class,
because your app was released by OS};
}
}
it is my implementation.
I'm working on a fairly complex Android application that requires a somewhat large amount of data about the application (I'd say a total of about 500KB -- is this large for a mobile device?). From what I can tell, any orientation change in the application (in the activity, to be more precise) causes a complete destruction and recreation of the activity. Based on my findings, the Application class does not have the same life-cycle (i.e. it is, for all intents and purposes, always instantiated). Does it make sense to store the state information inside of the application class and then reference it from the Activity, or is that generally not the "acceptable" method due to memory constraints on mobile devices? I really appreciate any advice on this topic. Thanks!
I don't think 500kb will be that big of a deal.
What you described is exactly how I tackled my problem of losing data in an activity. I created a global singleton in the Application class and was able to access it from the activities I used.
You can pass data around in a Global Singleton if it is going to be used a lot.
public class YourApplication extends Application
{
public SomeDataClass data = new SomeDataClass();
}
Then call it in any activity by:
YourApplication appState = ((YourApplication)this.getApplication());
appState.data.UseAGetterOrSetterHere(); // Do whatever you need to with the data here.
I discuss it here in my blog post, under the section "Global Singleton."
Those who count on Application instance are wrong. At first, it may seem as though the Application exists for as long as the whole app process exists but this is an incorrect assumption.
The OS may kill processes as necessary. All processes are divided into 5 levels of "killability" specified in the doc.
So, for instance, if your app goes in the background due to the user answering to an incoming call, then depending on the state of the RAM, the OS may (or may not) kill your process (destroying the Application instance in the process).
I think a better approach would be to persist your data to internal storage file and then read it when your activity resumes.
UPDATE:
I got many negative feedbacks, so it is time to add a clarification. :) Well, initially I realy used a wrong assumption that the state is really important for the app. However if your app is OK that sometimes the state is lost (it could be some images that will be just reread/redownloaded), then it is fully OK to keep it as a member of Application.
If you want to access the "Global Singleton" outside of an activity and you don't want to pass the Context through all the involved objects to obtain the singleton, you can just define a static attribute in your application class, which holds the reference to itself. Just initialize the attribute in the onCreate() method.
For example:
public class ApplicationController extends Application {
private static ApplicationController _appCtrl;
public static ApplicationController getAppCtrl()
{
return _appCtrl;
}
}
Because subclasses of Application also can obtain the Resources, you could access them simply when you define a static method, which returns them, like:
public static Resources getAppResources()
{
return _appCtrl.getResources();
}
But be very careful when passing around Context references to avoid memory leaks.
Dave, what kind of data is it? If it's general data that pertains to the application as a whole (example: user data), then extend the Application class and store it there. If the data pertains to the Activity, you should use the onSaveInstanceState and onRestoreInstanceState handlers to persist the data on screen rotation.
You can actually override the orientation functionality to make sure that your activity isn't destroyed and recreated. Look here.
You can create Application class and save your all data on that calss for use that anywhere in your application.
I know this is the very old question but using the ViewModel from the jetpack components is the best way to preserve the data between Activity rotation.
The ViewModel class is designed to store and manage UI-related data in a lifecycle conscious way. The ViewModel class allows data to survive configuration changes such as screen rotations.