0

I am building an Android app, which starts a service that keeps running in the background. When the user uses the Home button to close one of the activities (which communicate with the service), and then navigates to the app again, they get the last activity. This is correct behaviour.

However, when I explicitly stop the service (via an option in the menu), the app should "Quit". Currently, that works like this:

stopService(new Intent(this, MyService.class));

finish();

// just go to to the home screen, as it is intended in Android
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

and that works fine. But when I now navigate to the app again, it starts the previously opened Activity. What I want is that it starts the starting activity again (the launcher).

How could I accomplish that?

Bart Friederichs
  • 33,050
  • 15
  • 95
  • 195
  • `android:excludeFromRecents=["true" | "false"]` Have a look: http://developer.android.com/guide/topics/manifest/activity-element.html – An SO User Sep 17 '13 at 19:04
  • @Geobits yes it fires. `finish()` isn't actually doing anything on the main thread. But that's beside the point here. – Bart Friederichs Sep 17 '13 at 19:05
  • 3
    I would encourage you to rethink "Quit" in the first place. If by "Quit" you really mean something like "Logout", then use `FLAG_ACTIVITY_CLEAR_TOP` and `FLAG_ACTIVITY_SINGLE_TOP` to lead the user back to the starting point of your app, so they can choose to log in again (e.g., they accidentally pressed "Quit"). Beyond that, I'll point you to http://stackoverflow.com/questions/2033914/quitting-an-application-is-that-frowned-upon/2034238#2034238 – CommonsWare Sep 17 '13 at 19:13
  • It is not easy to accidently Quit, as you need to "slide-to-quit". Basically, "Quit" means: stop the service and close the app. When restarting, it needs to go through the service-startup again and a disclaimer. – Bart Friederichs Sep 17 '13 at 19:14
  • @CommonsWare adding `FLAG_ACTIVITY_TOP` to the `ACTION_MAIN` intent doesn't seem to do the trick. – Bart Friederichs Sep 17 '13 at 19:23
  • 1
    If all you need to do is restart services what is wrong with checking to see if the service is running and if not starting them in your `onResume()`. this way you are not properly using the android life cycle and structure – tyczj Sep 17 '13 at 19:31
  • @tyczj I'll reconsider some things in the design, but for now the spec says it needs to show a disclaimer when started afresh. – Bart Friederichs Sep 17 '13 at 19:39
  • @BartFriederichs so pop that up too when starting the services – tyczj Sep 17 '13 at 19:40
  • @tyczj Your solution turned out the solution I took. I actually was able to remove another pile of old cruft from my code (I'm in the process of cleaning up a lot of old handiwork that implemented all thie the Wrong Way ;)). – Bart Friederichs Sep 17 '13 at 20:45

4 Answers4

1
System.exit(0);

But you should have only one Activity in stack.

Taras Okunev
  • 410
  • 6
  • 9
0

If you look at the description of android:excludeFromRecents it says:

Whether or not the task initiated by this activity should be excluded from the list of recently used applications ("recent apps").

isn't this what you are looking for ? Once the user hits exit, this app won't be in the recently used apps and hence will be completely removed from memory ? :)

An SO User
  • 24,612
  • 35
  • 133
  • 221
0

I think that removing 'the app completely from memory on exit' is not the issue. Even if you stop your service the process is likely to remain in memory - that is the systems' decision.

You want an explicit, custom behaviour - user chooses your 'exit' option from menu --> next app launch starts at main activity - so you will need to handle this explicitly.

The default behaviour is that the user returns to their last activity when they re-launch. So they only return to the main activity if they exit by 'backing out' through your activities. Your use of an 'exit' menu option is non-standard (not to say it is bad).

One option would be to do the backing out through your activities yourself. Perhaps now you are just finishing the current activity and you should instead finish all the activities in the back stack.

Another option is that you could save a flag, and when the UI is launched again you could read that flag and launch the appropriate activity (but again be careful with the backstack). The easiest way to set that flag is probably by overriding onSaveInstanceState(Bundle) and then reading the bundle in onCreate (or use sharedpreferences).

Tom
  • 17,103
  • 8
  • 67
  • 75
  • The main activity is only used to start either a disclaimer, or one of two others, depending on the state os the service. You cannot go back because I disabled the back button. I know this is all non-standard behaviour, but the entire app is non-standard. – Bart Friederichs Sep 17 '13 at 19:37
  • I think non-standard is fine, it just means you need to take extra care, both with the code, and the users' expectations. In this case, I think you need to take that extra care with the back-stack. – Tom Sep 17 '13 at 19:40
0

Have you tried setting the clearTaskOnLaunch to true for your main activity (in your manifest).

From the documentation:

When the value is "true", every time users start the task again, they are brought to its root activity regardless of what they were last doing in the task and regardless of whether they used the Back or Home button to leave it.

This seems to describe what you want to do. I have never tried this personally, but it seems worth investigating for your purpose.

free3dom
  • 18,729
  • 7
  • 52
  • 51