I have created a Android contact-book application. But when I enter the application, go through 3-4 screens and accordingly various activities are called. After which if I press the back button repetitively I return on first screen of the application.
If here I press back button some or the other previously visited screen is shown again, rather the application should either exit or should go in background.
Where have I missed out some standards that causes me to be stuck?
In short, the back-button on the first-screen of application shows irrelevant previously visited screens of the Android application. So I'm unable to move application in background or exit.
This issue can have these causes:
The application wasn't closed before
If you are developing with Eclipse and the emulator and old version of your application does not necessarily get killed if you fix something and test the application again. Eclipse only tells the emulator to start the main activity.
So your Activity stack possibly looked this:
Main Activity -> Activity A -> Activity B -> Activity A
thus pressing back from the last one will bring up the Activities in the order
Activity B -> Activity A -> Main Activity -> Home-Screen
if you do not exit the application and just let the emulator create the Main-Activity again this will happen:
Main Activity -> Activity A -> Activity B -> Activity A -> Main Activity
Thus any actions from that point on will extend the activity stack but does not necessarily clean the old entries out of your stack. (this will only happen if the system considers them not necessary anymore and kills them)
Overriden methods
It is possible (but unlikely) that you have caused this behaviour yourself.
If you did not override methods such as onPause() you most certainly did not cause this. Some apps are forcing the start of an activity in the onPause()-method (which is very bad style, since this is not expected behaviour). This could change your activity stack.
Related
So my scenario is as such.
Let's say there is a MainActivity, which only job is to start, call installSplashScreen().setKeepOnScreenCondition { true } to show the Splash screen using the new backward compatible APIs, and then after checking some state it does startActivity(SomeActivity); finish()
Now we're on the SomeActivity and if we press the home button, the app is gone on the background. Then if we click on the launched icon, the SomeActivity is launched correctly, and the MainActivity's onCreate is never called, therefore the splash screen does not show again, and the SomeActivity shows instantly.
But if instead of pressing the home button, we press the back button, and the app is backgrounded that way, then when we click on the launcher icon, the MainActivity's oncreate is called again, and the splash screen icon flashes for a tiny fraction too making it look jarring.
My question is, does this sound like it's some wrong configuration on my part, or am I stuck with this behavior as long as I am not on a single activity architecture?
You are confused. Pressing the BACK button does not "send the app to the background". The default behaviour of the BACK button (assuming that you don't override this and provide your own behaviour) is to finish the current Activity. Normally this will take the user to the previous Activity in the current task. In your case, there is no other Activity in the task stack, so the current task is empty. This may appear to the user as "the app is sent to the background", but in reality there is nothing in the background. Your app's task is empty and so it is gone.
When the user then taps the app icon on the HOME screen or taps on the app's task in the list of recent tasks, there is no existing task to bring to the foreground, so the app is started again by creating a new task and launching the root Activity (in your case MainActivity) into the newly created task.
If you want the BACK button to just put your app into the background (instead of calling finish() on SomeActivity, which is the default behaviour) then just override onBackPressed() in SomeActivity and do this instead:
moveTaskToBack(true);
It seems like there is no solution to what I am facing as long as the Activity I want to resume to is not the Launcher activity.
From the the docs:
"Root launcher activities are activities that declare an Intent filter with both ACTION_MAIN and CATEGORY_LAUNCHER. These activities are unique because they act as entry points into your app from the app launcher and are used to start a task.
System behavior on Android 12 and higher
The system moves the activity and its task to the background instead of finishing the activity. This behavior matches the default system behavior when navigating out of an app using the Home button or gesture."
Reading the docs about the new back behavior on Android 12 and onwards tells us that pressing back when you got nothing else on the stack will act as if you pressed the home button.
There's a big exception here, and that is that when you re-open the application, if the one you just popped was not the launcher activity, it will then still need to launch that launcher activity and can't resume from where you left off in a hot state, exactly the reason why I am seeing the splash screen again.
So I think my best bet is to either ignore this for now, or fix my app to be a single-activity app, or at least keep the launcher activity be the top-level one that you exit the app from by pressing back
To indicate a couple of examples, if one wants to experience what I mean, the reproduction steps are to:
Open the app
Press the back button which will send you out of the app to the home screen
Click on the app icon again
As of today, apps like Google Photos, and Google Podcasts don't show the splash again. In contrast, apps like Google Maps, Twitter, Spotify do show the splash again for a brief second.
to call the launcher activity every time you have to clear the stack that means you have to use a flag in your manifest to tell your app not to keep activity in background try android:launchMode="singleTask" inside your activity tag in manifest the activity that you want to be killed everytime you go to background, and as far as how much time splash should be showing you can use timer for that after the timer is finished then your someActivity will be called.
I have 3 activities ( say A, B, C were A-is the Launch activity). When I press home button when at activity C, app goes into background. After that, I took my app through all apps list menu. At that time, my launch activity is showing (activity A). When I press back button, It goes to previous activity (C). I want to retain in the same activity (C) while coming back from background. When I run application through Eclipse, It works fine. But when I send Apk file through mail and run it in device, It fails (previous problem occurs ).
I tried with
android:launchMode="standard"
AND
android:alwaysRetainTaskState="true"
in my launch activity (Login activity or A). Any body please help me, Thanks in advance.
Follow following steps to insure that you are following the right practice:
1. Make sure you are using finish(); on the Activity A or B if you want to finish it and dont if you want the back button functionality.
2. Try Implementing onpause() and onresume() even if you are not going to perform any functionality in them. Use super() for them there.
3. Also, in android when you start an activity by clicking on the icon instead of resuming it from already running activities, it exhibits a different behaviour.
In my situation, there is one case in which I need to make sure the activity only runs one at a time.
I found if I set the LauchMode of the activity, I can reach the single instance aim, but it won't update the view of the activity.
This activity is launched by startActivityForResult, and we send the URI with the intent to the activity.
Let's discuss with this certain case:
gallery - lauch this activity with imageA.
camera - lauch this activity with imageB.
My request is not to destroy the old activity, but the activity that just received the new intent infomation should refresh the view.
I found a new method, onNewIntent.
This method can refresh the intent before resume. I will try it.
You can have an Activity with a manifest attribute of singleInstance.
As soon as the activity is relaunched , onResume gets called. You can update the view with the new image and invalidate the older View.
<activity ..
android:launchMode= "singleInstance" />
In your manifest, use android:launchMode="singleTask" instead of android:launchMode="singleInstance". Using singleInstance only returns to the existing instance if it is at the top of the stack. singleTask, on the other hand, return to the existing instance of the activity, as it is always at the root of the task.
Then, when your instance is launched, override onNewIntent to update your UI according to the new intent.
Refer to the Andorid documentation for details.
Be careful when using android:launchMode="singleInstance" in multiple activities application.
Here is my test on Pixel 4XL (Android 10)
Example, we have 3 activities (without declare taskAffinity)
A (entry activity)
B (start from A)
C (singleInstance, start from B)
If we start A->B->C. Now A,B in a task and C in a different task.
From C, press back -> will see B, press back -> will see A, press back -> app close. Everything working efine.
However, if we start A->B->C then press Home -> app go to to background.
Now there is 2 situations
User open app again from Recent app.
User will see C screen. Press back -> app will close (don't go to B)
User open app again by click on app icon
User will see B screen. Press back -> will see A, press back -> app will close (don't go to C)
The behaviour after open application is different between both case. But in both case, the application is always available in Recent app and you never able to remove application from Recent app (after remove it will appear again). Only able to remove it by Force stop in Setting.
If you run adb shell dumpsys activity activities, you will see that activities still exist in Stack, but you can not go back to it.
Another case
If we start A->B->C->A. Now A,B,A in a task and C in a different task (A is current visible to user).
From A, press back -> will see B (not C), press back-> will see A, press back -> will see C, press back -> app will close. (at least here we can go back to C)
Now if, we start A->B->C->A then press Home. In both case, user open app again by Recent or click on app icon, user will see A screen. Press back -> will see B, press back -> will see A, press back -> app will close (never see C screen)
Another note
The above example, although application run on 2 tasks but in Recent apps, it only show 1 task.
If you set the taskAffinity, in the Recent apps, you will see 2 tasks. In that case, you can choose the task which contain activity that you want to display but when you press back, it just go back to the activity in same task or close app (not able to go back to activity in another task).
Also, if you click on app icon to open app again, we have the same behavior like above demo.
I think singleTask and singleTop is less complex than singleInstance, so if it is enough for solve your problem, consider to use them instead of singleInstance
The problem is somewhat odd and after having trying to figure it out for about a day now, I am posting it here.
I have an application where an activity A(main activity) launches other activities(B,C or D).
The issue here happens when activity A has started Activity B and 'home' button is pressed.
Case 1 - When I test my application in debug mode on my device (HTC Desire) after pressing the 'home' button, I again click the application icon, it returns to the same activity (activity B), which is what is should do. No issues here.
Case 2 - When I export the signed package, and then install the application on the same device, then if I click the application icon after pressing the 'home' button, then a new instance of activity A (main activity) is launched ON TOP of activity B. I got to know this because when I press 'back' from that activity, it returns to activity B and pressing 'back' again shown activity A.
The behavior ceases to exist if the application is quit in the same order it was started, that is, if I press 'back' from activity B, then 'back' from activity A (exit).
After this everything runs fine.
I have tested it many times with different settings but I can't seem to figure out why the behavior is like this.
Any help is appreciated.
I think giving Activity A the 'single top' flag in your manifest should fix this.
Regarding Case 1:
When launching your intent from Activity A to start Activity B, add the flag FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
This will ensure that when you go home and launch the the app again, Activity A will be shown.
Regarding Case 2:
I'm not exactly sure how this would occur. It seems like it thinks you have two versions of the app, the signed one and the unsigned one but keeps them both in the same task stack. You may want to consider using singleTask or singleInstance for your Activity if you only want one instance. See the doc on tasks and back stack for more details.
I would agree with Noel regarding the likely cause of Case 2. Without task reparenting or it being set to a launchmode preventing multiple instances of an activity, there is a chance that launching it from Home isn't deemed the same stack as launching it from Eclipse (assuming this to be the case).
In my talent calculator app I have the whole application set allowTaskReparenting=true to ensure nothing is left in other stacks (primarily email as it can email launch urls). I then have my main activity set to launchMode="singleTask" as I only ever want one instance of this to exist no matter what launches it or with whatever intent.
My only other activity is for loading and saving and that has noHistory="true" to make sure it is removed and never returned to. That basically means it only exists while you're in it, and can never return to it.
clearTaskOnLaunch="true" will also ensure only the main Activity remains in the stack when it's launched from Home, but this isn't always the case if you have other ways to get into your activity. If it's only ever launched from Home then set this.
Hope that all helps.
Do you start you application manually or using Eclipse or another IDE? When starting from Intellij IDEA I had exactly the same problems. Then I stopped and ran it manually and behaviour was as expected.
I'm using a custom Launcher application with Widgets that are used to launch (and provide status updates) for an application.
The application consists of a few Activities - let's call them A, B and C for simplicity.
A is the launched Activity. The user proceeds from A to B and then to C (never in any other order).
At any time the user can press the 'Home' button on the remote control and return to the launcher application.
If the user then presses the 'Back' button on the remote control they always return to the Activity they were last using (A, B, or C).
However, if they click on the widget (rather than pressing back) the Activity that is brought to the front seems inconsistent!
So, here is an example of what happens
From (custom) launcher, use widget to launch application
Activity A appears
User presses a button that launches Activity B
Activity B appears
User presses 'Home'
Launcher appears
From (custom) launcher, use widget to launch application
Activity A appears NOT B
Sometimes I get Activity B instead of Activity A - but I'm not sure under what circumstances. I want to get the Activity at the top of the stack to be displayed and never any other Activity (Activity B in the example above).
I've read Google's documentation about the Activity flags ("single-task", "single-instance", etc...) but nothing seemed to jump out as the solution to my problem.
In my case, Activities A, B, C only make sense when run in that order - and it never makes sense to see a previous activity unless you explicitly go back to it.
I'm not sure if the problem is the way the widget is launching the application or whether there is something I need to specify in my manifest or something else.
Any ideas?
Thanks,
Dan
Isn't that what's supposed to happen? Isn't your widget launching activity A? Would you expect it to launch activity B if you are asking it to launch activity A?
(Althought you say that you get B launched sometimes. Isn't this related to the app being forced out of the memory?)
I'm sorry, but this is not an answer, but rather some additional information related to that same question.
I have found a pattern for Activities when relaunched after home button is pressed.
See my question for all my research:
Android Activity Stack is not working as stated in the docs - last activity in task stack not shown
Hope this can be of help...
I have been reading that the suggested fix for this strange behavior is the use of a "Dispatcher" class as Main that will launch the activity based on the application state...or you can also keep track of all the activities opened that need to be restored...but this can become really cumbersome when having a complex UI application design.