I can't find some informations about android application (not activities) lifecycle. My question is, how the application is working, when I treat it like a java programm - when it's initializing for example static objects. I'm adding a small graphic, that is showing my point of view - I'll be greatfull if someone could tell me, if I'm thinking correct :-)
For the application lifecycle, as per Android API Guide:
By default, every app runs in its own Linux process. Android starts the process when any of the app's components need to be executed, then shuts down the process when it's no longer needed or when the system must recover memory for other apps.
For static objects, they are initialized only once and are initialized when the class (which they are member of) gets loaded by ClassLoader. They will remain in memory until the class is unloaded. To read more about it, check this SO question
For activities, they have a clear lifecycle.
Related
As the title states,
Why is there a separate instance of VM(Dalvik/ART) for every App on Android?(the need for it)
and, what would have happened if the Android OS had chosen a model where a single VM runs all the apps?
There are many reasons why running multiple applications in a single process doesn't work; here's two:
Security zones.
Two applications that don't trust one another shouldn't be able to view each other's memory, even if they use native code or reflection.
Failure isolation.
If a process leaks memory and crashes, it harms only itself.
Why there is a separate instance of VM(Dalvik/ART) for every App?(the
need for it)
It is a design decision, and in my opinion, is made to keep it simple. Every process runs in its own vm. All the resources are allocated to that process, and the vm, internally, has not to coordinate access to resources, e.g. FileDescriptors, I/O etc. I never heard of multiprocess vm (a vm that allows more than one process to run in it), but I found an article that you could give you an insight.
I made the mistake of writing a Scala program for Android and relying on Scala Objects. Well the singletons where really handy when writing a game but now when the game ends, class instances that are loaded by the main Activity are GC:d like they should be, but the Scala Objects seem to stay in memory. So when I restart the game, the objects are in an unknown state instead of just initializing like when first starting the game.
So what would be the correct way of "destroying" these objects? In other words, how to make sure that some destroy code is run when the Android Activity ends?
You cannot. You have to turn them into classes and instantiate one instance of each in your main Game object, or whatever it's called.
Objects are singletons for the entire duration of the application (until the JVM shuts down). That's why they should typically not contain anything mutable.
I saw several places and people suggesting extending the Application class in their app.
Personally, I have never needed the necessity to do so.
I was not able to find a clear cut and direct answer by google-ing, so here are some questions :
What is an application class ?
why do we need it ?
Is it a singleton ? or we can have several instances ?
When we use it inside our manifest, is it the same as using the default application that usually eclipse generates ?
When are cases that extending it might be needed ? and when it is an overhead ?
Is it useful for caching purposes ?
It is something I have also thought about when I first started developing with Android and never came up with an answer. However just a quick google myself revealed this website.
Essentially I think it comes down to the fact if you are making a more involved Android application which would involve several Activity classes then things become difficult if you need to persist data that is to be shared between the various Activity classes of your application. Quoting from the above website:
If you take a look at the Application class (see here) in the API reference guide, you get a suggestion on how to manage global application data. The Application class, it says, is the “Base class for those who need to maintain global application state.”
If you've just started Android development this point may not be apparent to begin with however once you've worked with SDK for a while and you come up with an idea that you'd like to develop in a serious way you may hit upon this problem and then the reason for the Application class will become clear.
In the Android documentation there is quite good explanation what the Applications.class is.
Base class for those who need to maintain global application state. You can provide your own implementation by specifying its name in your AndroidManifest.xml's tag, which will cause that class to be instantiated for you when the process for your application/package is created.
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.
Sometimes you may need it to extend in order to work with external libraries. I did use it for UrbanAirship see here
The Application instance is indeed one for our app and it is created when our application starts and removed when it is closed. It represents general state of the application.
I am aware of the technique of extending the Application class to provide global storage. However in my case I am writing a class for a library function, so do not wish to force users of the class down this path. I have a requirement for some static class variables. I have seen passing references in StackOverflow that these might not be safe. However I've tried two different applications using the same class, and even when running both applications side by side on a Galaxy S3 in multi-window mode, the static class variables remain separate.
So, can someone with an in depth knowledge of Android internals confirm if this is safe or not.
If it is not safe, I can wrap the variables in a nested class and add them to a Serializable static HashMap, using the application package name as the key. This will force them to be safe. However if this is not necessary, then I'd rather not do it.
I have seen passing references in StackOverflow that these might not be safe.
They are not "safe" insofar as your process will be terminated from time to time, wiping out your static data members (and your custom Application, for that matter). Hence, static data members are good for a cache and not much else.
Within that scope, they are "safe".
You just need to make sure that this data is either stored somewhere persistent (e.g., file) or otherwise can be regenerated once the process is terminated and later is started up again. This is no different than with Application.
However I've tried two different applications using the same class, and even when running both applications side by side on a Galaxy S3 in multi-window mode, the static class variables remain separate.
Correct. Those are separate processes, with separate copies of your class and objects.
If your goal is to store persistant data across the twists and turns of the application lifecycle, then I would recommend not using static variables to do so. The obvious problem with this approach is that they could easily be garbage collected by the system when the operating system decides to reclaim memory (i.e. when the screen sleeps or a different application starts a memory-intensive task). I'm not sure what kind of data you are looking to "store", but I would recommend saving the state in SharedPreferences or an SQLiteDatabase instead.
I'm a little confused about what you're trying to do. You're trying to create a utility library in Java to be used by other applications? You're trying to create a whole Activity intended for use by other applications?
At any rate, as other posters have mentioned, applications can be killed at almost any time when resources become tight. There's simply no way to guarantee that static global values will remain resident in memory. You must provide a way to back it up on onPause() or onSaveInstanceState().
If you're writing a utility library, I presume that it returns some master object which holds all of its state. Add saveState(Bundle), restoreState(Bundle) methods to that object, and optionally saveToSharedPreferences() and restoreFromSharedPreferences() methods as well.
If it's an Activity you're writing, you're probably already familiar with the ways of saving state.
Me, I'm fond of combining the "singleton pattern" with shared preferences: https://stackoverflow.com/a/13673178/338479
You seem to have a deep misconception of how classes work.
Even if two classes are in the same package in two separate apps (by default) those apps run on separate VMs (i.e., processes). They literally have nothing to do with each other (as it should be, since otherwise you might get cross-app name collisions which is unacceptable).
What you're looking for is not a way to use static variables but a way to do inter-process communication (IPC). Android's Services are ideal for this, though there is a bit of a steep learning curve there.
I'm developing an Android app, and I already read about the lifecycle of an activity.
I don't know, what's happens if I don't implement the methods of the lifecycle onCreate(), onDestroy(), etc..
The JVM calls automatically these methods?
I'm habitual in iOS, and the change to Java is some peculiar for me. I want call the methods to manage memory.
I'm supponing that these methods helps to manage the memory in my App and this not crash in runtime.
The Android framework always calls those methods. If you don't implement them, the base class methods will be run. Typically they do nothing (significant). However, you definitely need to override some of the methods (at least onCreate) to make your activity useful.
As far as memory management goes, you usually should not worry about that at all. Java has automatic garbage collection that works very well. Unlike Objective C, in Java there is actually no mechanism for manual memory management; it's always done by the JVM. The only thing you need to pay attention to as far as memory management goes is to be sure you don't maintain hard references to large data structures that you no longer need. See the article Avoiding Memory Leaks in the Android blog.
If a method isn't overridden its base class implementation will be used.