Is overriding Application class and access it through static variable safe? - java

In my android application, I'm overriding Application class like below.
public class MyApplication extends Application {
private static MyApplication instance = null;
#Override
public void onCreate() {
super.onCreate();
instance = this;
}
public static MyApplication getInstance(){
return instance;
}
}
I'm doing this to keep my applicationcontext releted stuf(like database connection which I am creating with applicationcontext and using on entire application) between configuration changes and to access application instance without needing activity object(Activity.getApplication()).
Now the question is, is there any down sides of keeping application's static instance? I mean, according to my understanding, after Application.onCreate() gets called(which should only happens once), MyApplication.getInstance() should never return null. Is this true?
Also is there any way on Android to start Application instance more than once(without killing the old one)? If there is, what my static instance variable will points to after second instance stated? I'm guessing, because they will be different processes, each points to it's own application but i can't be sure.
PS: I am not asking about overriding Application class, I already know Dianne Hackborn(an Android framework engineer) says there is no need to override Application class, using Singletons instead should be fine. The question is more about application lifecycle and keeping static variable.

The short answer is, yes it is safe.
Before any other components in your application startup, the application class is loaded and onCreate() is invoked, so in every component of your application (Activity, Service, Database, etc) you are guaranteed to have an instance.
The other type of safety in terms of a memory leak is also fine consdering you are using this static throughout your app. The only thing to keep in mind is that the static will be in memory as long as the application process is running.

it is safe, as long as your application never runs in multiple processes. there's a strict one to one ratio of application per process. So, 2x processes means 2x application instances.

Related

Handling common code between different activities, fragments, tasks, etc

I have quite some (not too much, but quite some) experience with Java and object-oriented programming in other languages, but am fairly new to Android and my understanding of all its different classes is at best described as limited (more realistic would be confused).
I'm creating an application that for now consists of one activity and a widget. One of its functionality will be fetching some data from the internet. This data will only change every day on some arbitrary moment, so there's no need to fetch this data every time you start the app or look at the widget.
My problem is that I'd like to have one method to fetch the data and store it in shared preferences, together with the update time (so that it's only updated once a day). This method has to be accessible from the widget and the activity.
Normally I would simply create some class with a static method to do this. However, to access the shared preferences you need a Context. I can come up with two ways:
Option 1: static method, Context as parameter
public class MyClass {
public static String fetchData(Context context) {
return // ...
}
}
Option 2: singleton
public class MyClass {
private static MyClass instance = null;
private Context context;
public MyClass(Context context) {
this.context = context;
}
public String fetchData() {
return ...;
}
public static MyClass getInstance(Context context) {
if (instance == null)
instance = new MyClass(context);
return instance;
}
public static MyClass getInstance() {
return instance;
}
}
Now I would call it with MyClass.getInstance(getActivity()).fetchData() the first time, and after that MyClass.getInstance().fetchData().
My question
Is either of these preferred over the other, and if so, why? Or is there another, better, way to do this kind of thing? Or does it depend on the situation (and in that case, on what precisely?)?
Later, I may have more of these methods. Since the Context is something that normally doesn't change, I thought a singleton may be useful here because after the first instantiation you don't need to give a context anymore.
Option 1 is ok to use almost all the time. Option 2 is dangerous because you are keeping a reference to a Context. if the Context is of type Activity you can have memory leaks - your Referenced Activity will not be GC
If you are using option 2 make sure you are using Application Context.
To init the singleton do something like:
getInstance(myActivity.getApplicationContext())
option 1 is much better if the method is a utility method - does something and does not need to change it's state after the method has returned.
first of all you are not keeping a reference to Context. also you don't need to hold a singleton in the memory. Last Static methods are efficient.
Use option 2 if you are using the Singleton all the time and recreating objects during the process (Picasso, RetroFit are good examples for the need of Singleton)
A good example of when to use a Singleton is Android Volley library. It's also relevant to fetching data from remote so have a look
In essence, neither of your approaches are required for what you initially describe...
I'm creating an application that for now consists of one activity and a widget. One of its functionality will be fetching some data from the internet. This data will only change every midnight, so there's no need to fetch this data every time you start the app or look at the widget.
So what exactly is going to be responsible for the daily download and how is it going to be triggered? Neither an Activity nor an App Widget is suitable.
Add a few bits and pieces - use AlarmManager to create a repeating alarm set for around midnight (it won't be exact but normally within a few seconds). Have the alarm trigger a broadcast which is received by a BroadcastReceiver and then have the receiver start an IntentService to download and save what's needed.
It's a win-win scenario. The alarm will be fired regardless of whether your app is 'running' or not (or whether the phone is asleep or not). The receiver will be triggered and the IntentService uses its own worker thread so no need to worry about any problems with running network code on the main/UI thread. Also, an IntentService has a Context which can be used to access SharedPreferences and will shut itself down after it has done its work.

In Java, how can I run a static method whenever my class gets loaded or unloaded?

I have a class that uses static methods to wrap remote API calls.
Generally speaking, I don't want my API server to "listen" for these calls all the time, but instead only listen when the class is being used by a program. So I need a way to tell the server to "wake up" when the class gets loaded (how I send the "wake up" message is irrelevant).
I know that I can wake the server up when the first class method is invoked, but I want it to be ready as soon as the class is loaded into a running program (even if it is loaded lazily).
Also, it would be nice to know when the class is no longer used, so I can tell the server to go back to sleep.
Basically, I'm looking for a "constructor" and a "finalizer" of an entire class. Can this be done?
EDIT: A very important thing I forgot to mention, I can't have the user manually initialize/finalize the class using public static methods or anything like that. The class needs to feel like a regular native class.
You can use a Static Initialization Block:
class YourClass {
static {
System.out.println("I got loaded!");
}
}
This will be called at the moment the class gets loaded by the JVM.
For the unloading part, a way (neccessarilly not the best) is to start a timer in the static initializer in which you close the resources after a certain time of no usage. Usage would be indicated by a constructor being called or something like that, but it might be tricky to implement with concurrency issues.
Another way could be to write a custom Classloader.

Differences between a service and a singleton instance?

I'm developing an android application, and would like to know the difference between a service started with startService() and a singleton class performing the same code I put in startService().
So, for example if I have a VideoRecordingService service set to record a video from the camera on it's start, and a CameraRecorderClass singleton class which have a StartRecording() method that also records a video from the camera, how do they differ?
They both non-related to any activity lifecycle, and they both use the main thread to do it's work.
Thanks
Service is mainly used when you want to do some background operation. For eg:- Playing music in your application. So, if you don't have any Activity running you can play music using Service.
While your Singleton instance would not be working if you close your application/activity if unless you are performing it in some background task. Also, Service will restart automatically if you return START_STICKY from onStartCommand when your Service is killed due to some reason.
So, in your case if you really want to do some long background running operation then its better to use Service instead of your Singleton instance.
When using startService it creates a new instance of that class, it can have a context and do a wide range of things that the Service class inherits. You can create this anywhere in your application where you have a context, and you can start and stop it multiple times (using startService and stopSelf)
With a singleton class, well, its a static object that you can only have once instance of (unless you want to create more I guess?). The static object can isn't much different, however it doesn't have a context and all that nice android stuff that comes with a class (unless you pass it a context or what ever you may need).
A service can also be run without needing to invoke it by using a activity, or showing a UI, it can run in the background with no UI, and can be started using a broadcast listener without interrupting the user, as long as the service is running then the service shouldn't be automatically closed by the system, rather then if you started an async task in the singleton and then closed the activity and the activity was destroyed.
There may be more to it. But you would have to look into dalvik..

What is the best equivalent of a main() function for an Android app?

I've searched everywhere a manner to have the equivalent of a main() function (yes function not method) inside a Android application but failed...
Typically what I would want to do is:
void main()
{
// do some really nice initialisations stuff here
// ... let the app does his life, I really don't care
// do some final stuff here before leaving
}
The nearest approach I've seen so far is to use a SplashScreen and override the OnCreate() method. The problem is that is not acceptable from my point of view.
Why? Because a SplashScreen is nothing than an Activity tagged as a LAUNCHER.
That makes it to appear in the apps list, thing I don't want when I develop an app widget.
Furthermore, where to place my code just before the app destroy? In the onDestroy() method?
No, once again, this is not reliable. Android can decide to delete my instance whereas the application is still running.
Well, in fact, I take for principle that every components of my app are running in the same process since I don't mention explicitely in the Manifest that I wan't a component to run in its own process.
In the case of an app widget, I've placed my init code on the first call of onUpdate() method. I think it's a good bet. Then this app widget (AppWidgetProvider more precisely) is in charge to launch any activity as its will.
The "DataBase" for all the app is defined in a separate Singleton like this:
public class MyDataBase {
public static MyDataBase getInstance() {
if (instance_ == null)
instance_ = new DataBase();
return instance_;
}
public void load();
public void save();
static MyDataBase instance_ = null;
public int myInt;
public String myString;
public Object myObject;
etc..
}
With this Singleton I'm sure at least, its lifecycle is the same as the entire app itself.
To back with that AppWidgetProvider, I have to trick a little. Indeed, Android can decide to delete its instance whereas some other activities are still on place and the process is still running. So for example, systematically loading my DataBase in the first call of the OnUpdate() is unnecessary and overkill. What I do is having a static boolean value that indicates if the DataBase have been loaded for the lifecycle of this process or not.
Thus, the AppWidgetProvider can be instanciated tons of time, as long as the Singleton DataBase persists (so the process), it will not reload the DataBase each time, got it?
(yes difficult to be clear...)
About the cleanup code of the app, I thought to override the finalize() method of my DataBase Singleton, but well, I'm really not sure it's a good idea since the moment of the call of this method is totally unpredictable. I suppose it would be called if you suddently power off your Android, but well I'm not sure of anything here, thus so far, I didn't found a solution for that part.
Any comment or something less tricky that what I currently do is welcome.
Thanks.
onResume() is the function that will be invariably reached before starting you app, so you could either put the 'main' code in the onCreate() method or the onResume().
onPause() is ALWAYS called before destroying the app, either by the user or the OS.
There is great explanation regarding the lifecycle in the Android documentation:
http://developer.android.com/training/basics/activity-lifecycle/starting.html
For the initialisation you can over-ride the onCreate method of the Application class:
Called when the application is starting, before any activity, service, or receiver objects (excluding content providers) have been created. Implementations should be as quick as possible (for example using lazy initialization of state) since the time spent in this function directly impacts the performance of starting the first activity, service, or receiver in a process. If you override this method, be sure to call super.onCreate()
Termination is harder to deal with. You'll probably have to monitor each component of your application separately. If you are targeting API level 14 or later you can use Application.registerActivityLifecycleCallbacks to help with this.
The nearest approach I've seen so far is to use a SplashScreen and
override the OnCreate() method. The problem is that is not acceptable
from my point of view. Why? Because a SplashScreen is nothing than an
Activity tagged as a LAUNCHER.
It's because Android is formed with several activities and those activities have life cycles. So every activities start from onCreate() then finishes at onDestroy().
http://developer.android.com/training/basics/activity-lifecycle/starting.html
That makes it to appear in the apps list, thing I don't want when I
develop an app widget. Furthermore, where to place my code just before
the app destroy? In the onDestroy() method? No, once again, this is
not reliable. Android can decide to delete my instance whereas the
application is still running.
In a scenario that user presses home button to exit from your app, your current activity is more likely to invoke onPause() method (only when the activity has no other processes to finish). However, when user force closes (terminates) your whole application by ending process. Then you don't have to worry about invoking any methods or what so ever because Android itself will close anything related to your application automatically.
To back with that AppWidgetProvider, I have to trick a little. Indeed,
Android can decide to delete its instance whereas some other
activities are still on place and the process is still running. So for
example, systematically loading my DataBase in the first call of the
OnUpdate() is unnecessary and overkill. What I do is having a static
boolean value that indicates if the DataBase have been loaded for the
lifecycle of this process or not. Thus, the AppWidgetProvider can be
instanciated tons of time, as long as the Singleton DataBase persists
(so the process), it will not reload the DataBase each time, got it?
(yes difficult to be clear...)
The example you have posted for singleton database connection is not bad I think, but there are better ways to get the job done cleanly and more effectively. For example hibernate framework connection pooling

Static references are cleared--does Android unload classes at runtime if unused?

I have a question specific to how the classloading / garbage collection works in Android. We have stumbled upon this issue a few times now, and as far as I can tell, Android behaves different here from an ordinary JVM.
The problem is this: We're currently trying to cut down on singleton classes in the app in favor of a single root factory singleton which sole purpose is to manage other manager classes. A top level manager if you will. This makes it easy for us to replace implementations in tests without opting for a full DI solution, since all Activities and Services share the same reference to that root factory.
Here's how it looks like:
public class RootFactory {
private static volatile RootFactory instance;
#SuppressWarnings("unused")
private Context context; // I'd like to keep this for now
private volatile LanguageSupport languageSupport;
private volatile Preferences preferences;
private volatile LoginManager loginManager;
private volatile TaskManager taskManager;
private volatile PositionProvider positionManager;
private volatile SimpleDataStorage simpleDataStorage;
public static RootFactory initialize(Context context) {
instance = new RootFactory(context);
return instance;
}
private RootFactory(Context context) {
this.context = context;
}
public static RootFactory getInstance() {
return instance;
}
public LanguageSupport getLanguageSupport() {
return languageSupport;
}
public void setLanguageSupport(LanguageSupport languageSupport) {
this.languageSupport = languageSupport;
}
// ...
}
initialize is called once, in Application.onCreate, i.e. before any Activity or Service is started. Now, here is the problem: the getInstance method sometimes comes back as null -- even when invoked on the same thread! That sounds like it isn't a visibility problem; instead, the static singleton reference hold on class level seems to actually have been cleared by the garbage collector. Maybe I'm jumping to conclusions here, but could this be because the Android garbage collector or class loading mechanism can actually unload classes when memory gets scarce, in which case the only reference to the singleton instance will go away? I'm not really deep into Java's memory model, but I suppose that shouldn't happen, otherwise this common way of implementing singletons wouldn't work on any JVM right?
Any idea why this is happening exactly?
PS: one can work around this by keeping "global" references on the single application instance instead. That has proven to be reliable when one must keep on object around across the entire life-time of an app.
UPDATE
Apparently my use of volatile here caused some confusion. My intention was to ensure that the static reference's current state is always visible to all threads accessing it. I must do that because I am both writing and reading that reference from more than one thread: In an ordinary app run just in the main application thread, but in an instrumentation test run, where objects get replaced with mocks, I write it from the instrumentation thread and read it on the UI thread. I could have as well synchronized the call to getInstance, but that's more expensive since it requires claiming an object lock. See What is an efficient way to implement a singleton pattern in Java? for a more detailed discussion around this.
Both you (#Matthias) and Mark Murphy (#CommonsWare) are correct in what you say, but the gist seems lost. (The use of volatile is correct and classes are not unloaded.)
The crux of the question is where initialize is called from.
Here is what I think is happening:
You are calling initialize from an Activity *
Android needs more memory, kills the whole Process
Android restarts the Application and the top Activity
You call getInstance which will return null, as initialize was not called
Correct me if I'm wrong.
Update:
My assumption – that initialize is called from an Activity * – seems to have been wrong in this case. However, I'll leave this answer up because that scenario is a common source of bugs.
I have never in my life seen a static data member declared volatile. I'm not even sure what that means.
Static data members will exist until the process is terminated or until you get rid of them (e.g., null out the static reference). The process may be terminated once all activities and services are proactively closed by the user (e.g., BACK button) and your code (e.g., stopService()). The process may be terminated even with live components if Android is desperately short on RAM, but this is rather unusual. The process may be terminated with a live service if Android thinks that your service has been in the background too long, though it may restart that service depending on your return value from onStartCommand().
Classes are not unloaded, period, short of the process being terminated.
To address the other of #sergui's points, activities may be destroyed, with instance state stored (albeit in RAM, not "fixed storage"), to free up RAM. Android will tend to do this before terminating active processes, though if it destroys the last activity for a process and there are no running services, that process will be a prime candidate for termination.
The only thing significantly strange about your implementation is your use of volatile.
Static references are cleared whenever the system feels like it and your application is not top-level (the user is not running it explicitly). Whenever your app is minimized and the OS wants some more memory it will either kill your app or serialize it on fixed storage for later use, but in both cases static variables are erased.
Also, whenever your app gets a Force Close error, all statics are erased as well. In my experience I saw that it's always better to use variables in the Application object than static variables.
I've seen similar strange behaviour with my own code involving disappearing static variables (I don't think this problem has anything to do with the volatile keyword). In particular this has come up when I've initialized a logging framework (ex. Crashlytics, log4j), and then after some period of activity it appears to be uninitialized. Investigation has shown this happens after the OS calls onSaveInstanceState(Bundle b).
Your static variables are held by the Classloader which is contained within your app's process. According to google:
An unusual and fundamental feature of Android is that an application
process's lifetime is not directly controlled by the application
itself. Instead, it is determined by the system through a combination
of the parts of the application that the system knows are running, how
important these things are to the user, and how much overall memory is
available in the system.
http://developer.android.com/guide/topics/processes/process-lifecycle.html
What that means for a developer is that you cannot expect static variables to remain initialized indefinitely. You need to rely on a different mechanism for persistence.
One workaround I've used to keep my logging framework initialized is for all my Activities to extend a base class where I override onCreate and check for initialization and re-initialize if necessary.
I think the official solution is to use the onSaveInstanceState(Bundle b) callback to persist anything that your Activity needs later, and then re-initialize in onCreate(Bundle b) when b != null.
Google explains it best:
http://developer.android.com/training/basics/activity-lifecycle/recreating.html

Categories

Resources