I have an application where the entry point is let's say a "login/splash" Activity
, where I need to pre-load fresh data from the server. This SplashActivity
is declared as :
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
in my AndroidManifest.xml
, after data is loaded, I keep some data on my custom Application
class and I proceed to my MainActivity
.
I am expecting, that after my Application
is stopped by the OS or by the user (using Force Stop), and then later is re-started by the user, the entry point of my application to be SplashActivity
again BUT the system skips the SplashActivity
and displays the MainActivity
.
QUESTION: is this the expected behaviour? If the entire process is stopped, shouldn't my application be started with SplashActivity
? Can this be accomplished?
Actually, there are several problems that are addressed by this question and some of the answers to it:
To answer your original question, "Yes, this is the expected behaviour".
Android considers each Activity to be a separate self-contained entity. Android remembers the state of activities in the task stack and it has no problem killing your process (which contains all your activities) whenever it wants to, because it "knows" that it can always reconstruct your activities whenever it needs to. This concept, of course, breaks down when you have a complex application where you have dependencies between the activities and/or you have global data that you store in an
Application
class (or similar static/singleton place).When Android kills your process it remembers the topmost activity in the task and when the user returns to the task it recreates the process and then recreates only the topmost activity in the task. In your case,
MainActivity
.As an example, if your task stack looks like this:
and your task goes to the background and Android kills the process, when the user returns to the task only
ActivityD
will be recreated. OnceActivityD
is finished, Android will then recreateActivityC
. OnceActivityC
is finished, Android will recreateActivityB
, etc. In short, the complete stack is not recreated when the user resumes the task.There is no combination of manifest settings or Intent flags that will get you the behaviour that you want. It would be nice if Android offered something like that, but at the moment it does not.
You can determine if your process has been restarted by using a static (class) boolean variable in your Application-derived class (or in any other class). This variable will always have the value
false
when the process is restarted and you can then check the state of the variable from anywhere and reinitialize (reload your data) if necessary. Then you set the variable totrue
. It will remaintrue
until the process is killed and recreated, even if all your activities finish. In this way you can initialize only when needed.You can also use this as an indicator to restart your application from the
SplashScreen
. So in all your activities, inonCreate()
, you can check the state of this boolean variable and if the application has been restarted you can simply redirect to theSplashScreen
like this:This will finish all the activities in the task and restart the
SplashScreen
at the root of the task.Next, if you want to prevent having to download data every time the user returns to the application (when it was in the background and subsequently killed by the AndroidOS), you should store the data that you download in the private cache area and use that when the application is restarted. This prevents having to download the data repeatedly if your process is killed and restarted.
Another way of dealing with this would be to load your data in a Service. If you have a
Service
running in your process then Android is less likely to kill your process. You just need to make sure that you shut down yourService
when the user is finished with your application.I realize this answer is long-winded. Hopefully you can get something out of it.
It can be done like this:
1.
SplashActivity
will start no doubt every time.2. Download the data and save the check(boolean) indicating the loading is done previously.You can use SharedPreferences.
3. Check the condition next time and start your
MainActivity
immediately.