I have an application which has two activities A and B. When application is installed and run for the first time then it always starts with A as it is declared as launcher activity in manifest.
According to workflow, after a few seconds, activity A is destroyed and activity B is started. So that, the root of task becomes B. Now, when user presses the home button and later comes to our app, activity B is resumed as expected. But, if application is left in background for a long time then the application is restarted as from the logs Application::onCreate() is called. However, I want that whenever the application restarts that is whenever Application::onCreate() is called (like in the second case) activity A should be started instead of B, in all other cases when application is not restarted activity B should be appearing. I am new to android and unable to figure out a solution. Any help is much appreciated.
Thanks in advance.
Use SharedPreferences : http://developer.android.com/reference/android/content/SharedPreferences.html
In the end of your activity A you should create a preference that save the a state of your app in the SharedPreference.
at the start of onCreate() of your activities check the state and start the correct activity.
Related
I have an application that implements two activities. Activity A is for selecting some files on device and activity B is to show additional info while these files are processing. Both of them have singleInstance as launch mode.
On application's start activity A runs. Then this activity starts second activity B, that creates a notification. If I tap this notification or open running app from recents, it works fine and shows running activity B. But if I'd started application before and activity B is already running, launching it again from app menu causes showing activity A when old activity B is already running and accesible from notification bar.
So, what should I do to make application run only single activity at the same time and show second activity when called from launcher (if second activity once started and isn't finished)?
Your launcher intent should be mapped to a dummy activity, with no view (or may be a splash who knows !). In onCreate of that dummy activity you check if a state was saved previously and based on the state switch to the desired activity.
And how to set the state ? well lets try something simple. lets say when Activity A resumes we put "A" to some key in SharedPreference. if Activity B resumes we put "B" to the same key in preferences. Now your application goes out when Activity B was visible, the state saved would be "B", you launch from home screen, the dummy activity finds "B" in the state and launch intent to go to B else go to A.
My Android application(Application A) launches another application (say Application B) upon click of a button.
Now I want to implement "auto start" functionality wherein Application B will be launched as soon as Application A is launched.
For this, I created a checkbox and used SharedPreferences to store the value of checkbox.
Then, in my onCreate() method of Activity A, I am checking the value of checkbox from SharedPreferences and launching Application B in case the value is "true".
The Problem:
The problem I am facing is, when the user exits "Application B" (and comes back to Application A) the onCreate() of Application A is getting called again and Application B opens up again. This sets off a infinite loop and at exit of Application B, user returns to Application A and goes to Application B again.
I know onCreate() gets called multiple times (when we change orientation, keyboard opened, Activity goes into background and is killed by system), but is there any clean way of doing this?
To reiterate, my requirement is to launch Application B from Application A if the "auto start" checkbox is checked in Application A.
My suggestion will be to use the method onPause of the activity in application A and set a flag there "application B was called". Then if this flag is set do not call application B in onCreate of the activity in Application A and unset the flag.
If application B is too long in the foreground application A might be suspended by the system and the flag will be reset. In such case maybe it is good idea to have the flag stored in some persistent storage (e.g. SharedPreferences).
EDIT One more thing: the flag should be set in onPause only if the activity is being paused, because the other application will be shown (this will be easily determinable, because everything happens in the same class).
I have two activites...one in A application and other in B application.
I am calling activity from A app to B app so A app activity will be in pause and throw an intent to B app activity
and after B app activity, I will go back again to A app activity so A app activity should start from onrestart or onresume() as it was in onPause() but it is going to oncreate(). I am sure that the A app acitivity was not destroyed because when I hit back button it starts from resume or restart state.
Basically the two app activities runs in circular fashion like
A app activity- B app Activty- A app activity - B app activity ......................... so on
One more think I see is none of them are destroyed when I hit back button then it goes to resume state so nothing is killed.
Is there any way so that my transition shld be -
A app activity - B app activity ( A pause state- B on create state)
B app activity - A app activity ( B on pause state- A resume state)
Note: two activities from in diff apps
A lot of it will depend how you go from one activity to another and how you declared them in the manifest.
Without more code, I suggest you read the documentation here, especially pay attention to taskAffinity and launchMode
I will go back again to A app activity so A app activity should start from onrestart or onresume() as it was in onPause() but it is going to oncreate()
as #Eigor mentioned - the operating system can shout activities which stopped (not visible, and somewhere in the activity stack of the current process) in this case - Android OS will shout down the Activity without going throughonDestroy() , but will go through the onSaveInstanceState() callback for giving you a chance preserving any data state you'd like to restore when the activity will re-created when you'll hit the back button. the data you saved previously will be stored in the bundle param in the onCreate()
read - http://developer.android.com/reference/android/app/Activity.html#onSaveInstanceState(android.os.Bundle)
I guess because you don't knew that that's how the OS behaves it felt strange.
knowing that knowledge and taking it into consideration should solve your problem
I am sure that the A app acitivity was not destroyed because when I hit back button it starts from resume or restart state.
the fact that A app activity was not destroyed in this scenario is not something you can count on, and it does not contradict what I've said before. it still in some cases be shout down by the OS without onDestroy been call from the same reason.
about all the circulation you want to do between A and B: I think what I wrote can help you understand why it doesn't worked as you expect...
I have activities in sequence as Activity A calling Activity B,When I am on Activity B I press Home button and start another Application (for example Map). If i stay on this second application for a long time say 5-10 minutes and then press Home Button again and choose to Start my application again, then Activity B is started again and works fine. But when i Press Back key - I return to my Activity A again (which is also correct) but it shows a Blank Screen. Ideally in correct version it should show me Acitivty A with the XML data is ListView form.
Alternatively, in the above description, when the other Map Application is started and if the user stay on it only for 1-2 minutes then the above problem doesnt not occur.
Can anyone suggest a solution on the same.
Is it that i need to check in Activity B whether Activity A is still there in Activity Stack (How do i do the same) and If its not in my Activity stack then re-create it.
I tried doing alwaysRetainTaskstate in my Android manifest file for Activity A. But it doesnt work at all
You don't have to do any of that, Android takes care of the technicalities for you - it will recreate your Activity A.
You just need to remember to save A's state when B is opened (take a look at Activity.onSaveInstanceState). When A is restarted, your saved state will be passed to onCreate.
You should really read about Activity Lifecycle
This should help.
Long story short, I have a LaunchActivity which is always called by LAUNCHER (i.e. the home screen). It then starts LoginActivity and then closes itself.
This is the flow:
User launches app
LaunchActivity starts, starts
LoginActivity and then calls
finish() on itself (At this point
LoginActivity is the only Activity
on the stack)
User press "Home" button, stopping
LoginActivity
User launches the app again
When the app is launched for the 2nd time, two things can happen:
LaunchActivity starts, finishes
itself and then STARTS LoginActivity
LaunchActivity starts, finishes
itself and then CREATES
LoginActivity, so there are now two
LoginActivitys on the stack.
(2) seems to happen when I restart Eclipse and the simulator (yeah I know, black magic).
Some extra info: I'm not using any start flags and my manifest doesn't have any launchModes defined.
I think you want to set android:launchMode="singleTask" There's a basic explanation here:
http://groups.google.com/group/android-developers/browse_thread/thread/e29bd82a7fec43c6/44835d74b0af3f5f?lnk=gst&q=ellipsoidmobile#44835d74b0af3f5f
From the link "If your activity is launched from another application, without using single
task, but you want this to cause your current app to come to the foreground
instead of a new instance of that activity started in the other app's task.
An example of an app that does this is the browser. "
From reading your question, this looks like what you want. Set launchMode="singleTask" on your LoginActivity and when your LaunchActivity starts the LoginActivity it should restart the existing one instead of creating a second instance.
I imagine it has to do with whether or not the LoginActivity needed to be killed while it was in the background. As the activity lifecycle explains, an activity that is stopped (not visible) can be killed if the system needs to resources.