How to prevent recreation of a singleTask activity on back button press? - android

I have a simple launcher app, that doesn't launch any apps, just shows a WebView. It is set as the default launcher. I don't use any other apps on this tablet. When I restart the tablet, this launcher starts as expected. My problem is if I press the back button of the device, the activity is destroyed, and it is created again as a new activity. I don't get what's the point of this behaviour, as the activity is already visible... The view's launch mode is singleTask, so I expect it to just simply stay where it is, rather than being recreated. How can this be done? As far as I understand the documentation, this should work as I expect it, instead of the way it does now.
The system creates the activity at the root of a new task and routes
the intent to it. However, if an instance of the activity already
exists, the system routes the intent to existing instance through a
call to its onNewIntent() method, rather than creating a new one.
http://developer.android.com/guide/topics/manifest/activity-element.html#lmode

You can override onBackPressed() and do nothing like
#Override
public void onBackPressed() { }

Related

Why a "home" activity will be killed when the home button is pressed?

I have created an activity , set it's filter as a Home activity and set launchMode with singleTask. When I press home ,the activity will be in onpause state then onStop . What confuse me is why the activity will be re-launched when back from icon displayed on "home pick" dialog ? It calls onCreate() again without invoked onDestroy().
I know there is a way to solve this problem that is to set launcherMode as singleIstance, but this way is not good enough, because it will cause an other issue that the activity will not be able to process onActivityResult.
You may want to tell what you wish to achieve. Because that's how singleTask is. It delivers existing intent to onNewIntent() of the existing instance of activity. So activity will not be destroyed but onCreate() will be called, as it will reCreate activity with existing intent.
Quoting the documentation
The system creates the activity at the root of a new task and routes the intent to it. However, if an instance of the activity already exists, the system routes the intent to existing instance through a call to its onNewIntent() method, rather than creating a new one.

Android - Out of Memory Error due to starting a lot of Activities started

I have an application that implements somewhat like having a top page.
So like, i have this activities:
TopActivity , FirstActivity, SecondActivity, ThirdActivity and FourthActivity.
Each activities has a button that when you press it, it will bring you back ti the TopActivity.
The way I implemented this one is every time that button is pressed, I start an activity, a new TopActivity. So, every time a top activity button is pressed, it always create a new activity. If I also will finish() the TopActivity when it goes to first, second and third, I can not go to TopPAge using back button. Are there itger ways to do this?
Any help is greatly apprieciated.
You can use a different Launch Mode for you activities. The launch modes decides when and how to create a new Activity or reuse a previous one.
The singleTask launch mode seems like it would do the trick for you:
The system creates the activity at the root of a new task and routes
the intent to it. However, if an instance of the activity already
exists, the system routes the intent to existing instance through a
call to its onNewIntent() method, rather than creating a new one.

How to launch the activity of this case?

I have 3 activities in my app.
Home -> List -> Detail
When I am in Detail activity, I want to have a home button that will redirect me to Home activity and close the other activities. Then, I tried this code:
Intent intent = new Intent(this, HomeActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
since the FLAG_ACTIVITY_CLEAR_TOP is:
If set, and the activity being launched is already running in the
current task, then instead of launching a new instance of that
activity, all of the other activities on top of it will be closed and
this Intent will be delivered to the (now on top) old activity as a
new Intent.
I got what I want, but then it still goes to onCreate. Is there any way to launch the home and not going to its onCreate?
Your thinking and Android's are not yet fully compatible. ;)
When you "launch the home", that means it's going to be launched, and that means it's going to be created.
You can, however, use Activity.startActivityForResult() to start List and Detail. Your "home" button then will finish your Detail Activity. In the onActivityResult callback of List, you'll just pass through using Activity.finish(), and in onActivityResult of Home you'll just catch the event and know that you're now back.
You cannot control the Activity life cycle. It's up to Android to decide which activities to keep running and which to close. This means that when an Activity loses focus, it is not necessarily destroyed or closed, but might simply lost focus and keep running, but might also not. This is up to Android; you cannot control this behavior.
If you want to recover an Activity in a given state, you have to save all needed data and restore it in onCreate().

Switch between existing activities in Android

So I am developing this small game, it currently uses 2 activities:
The Menu Activity and the actual Game Activity;
The Game Activity is started by the Menu Activity (no problems at that)
Then I can switch from the Game Activity to the Menu Activity by using the back Key:
public void onBackPressed() {
super.onBackPressed();
}
Now I am back in the Menu Activity. The Game Activity I've created has been stopped(I guess);
How do I go back to the Game Activity, as I left it(how do I restart it)?
You need to manually save the state of your game using any of the methods described in Data Storage.
However if you start a new copy of the Menu Activity:
Menu Activity ->
Game Activity ->
Menu Activity
You can return to the Game Activity rather than completely rebuilding it. But of course, there is no guarantee that game Activity won't be destroyed by the garbage collector, so you still need to save the Game's state in onPause().
It is absolutely pointless to override a method just to call super. Please re-check what overriding means : if you don't override, then your subclass method A will be the same as super class method A. Thus, you can override to create a different version of A in your subclass, but not to call the super class method A, it is useless.
About the Activity, in android, you can't hope than activity that is not on the stack will be preserved. You can add this to your manifest :
<activity name=".GameActivity"
...
android:launchMode="singleTop" />
but even though, it will not guarantee that android will just clean up your activity and recreate it when it is relaunched. That's the way android preserves resources.
But a better way would be to call (startActivity) MenuActivity again from inside GameActivity. That way, your old GameActivity will still be in the activity stack. But really, there will always be some limit cases where android will recreate GameActivity. For instance, if system is under memory pressure.
The best is to persist the state of GameActivity so that even a new instance will be re-put in the same state as the old instance was.
Assuming you are using the menu as a sort of "pause" menu where the back button pauses the game, you could have the back button create a new intent for the menu activity and then let the back button from the menu activity function as normal.
Of course, you should still preserve game data when you launch the menu activity - since the user could close the screen from the menu - but the system will inherently keep your game activity (and data) in memory when you launch the menu.
#Override
public void onBackPressed() {
Intent intent = new Intent(GameActivity.this, MenuActivity.class);
startActivity(intent);
}

How to make an activity stop, rather then be destroyed, from the BACK key?

Right now an activity gets destroyed when the BACK key is pressed. How can I make it just stop ( i.e. keep all the variables, etc. alive ), rather then be destroyed?
Thanks!
Why is it that you need to keep the variables alive? Given the established lifecycle of an Android application, I'm not sure that preventing the activity from being destroyed "just to keep the variables" makes sense.
Even if you stop the application without destroying it, there is always the chance that Android will kill it to free up memory. You will have to account for this in your code anyway, and so preventing the application from destroying doesn't save you from writing code.
Variables can be saved and restored relatively easily and quickly using SharedPreferences in your onPause() and onResume() methods. Unless you are storing a ton of data, preventing the application from destroying might not make much of a difference.
It sounds like you want to keep the variables in memory because you intend to return to this activity. Typically, you don't use the back button to navigate away from activities that you intend to come back to. Instead you would create an Intent and start a new activity. When you do this, Android places the current activity on the Back Stack calling onPause() and onStop(), which seems like exactly the sort of behavior you are looking for.
So if you still really want to prevent your activity from being destroyed (at least until Android decides it's using too much memory and kills it on it's own) you could always use Sagar's code and start a new activity in onBackPressed().
#Override
public void onBackPressed()
{
Intent intent = new Intent(this, Other.class);
startActivity(intent);
}
Just be certain that that is what you really want to do.
Simple one line
#Override
public void onBackPressed() {
mActivity.moveTaskToBack(true);
}
Pressing the BACK key triggers the onBackPressed callback method of Activity class. The default implementation of this callback calls the finish() method.
http://developer.android.com/reference/android/app/Activity.html#onBackPressed()
You can override this method to move the activity to background (mimick the action of pressing the HOME key.
eg:
#Override
public void onBackPressed() {
onKeyDown(KeyEvent.KEYCODE_HOME);
}
You could also instead consider moveTaskToBackground() mentioned here:
Override back button to act like home button
I have managed to work out exactly what you want: switch between 2 activities using Back button and keep them all not to be destroyed!
For example: you have 2 activities A & B. A will be started first, then A calls B. When B is loaded, user press Back button and switches back to activity A from B. From now B should not be destroyed and just goes to background, and when user starts activity B from A again, activity B will be brought to foreground, instead of being re-created again or created new instance! How to implement this:
1. Override onBackPressed() of activity B:
#Override
public void onBackPressed() {
Intent backIntent = new Intent(this, ActivityA.class);
backIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(backIntent);
}
2. On activity A, call activity B:
public void callActivityB() {
Intent toBintent = new Intent(this, ActivityB.class);
toBIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(toBintent);
}
remember to add flag: Intent.FLAG_ACTIVITY_REORDER_TO_FRONT when you call A&B.
This is similar to this question that was asked earlier.
Hope this helps!
N.S.
First of all, sorry for not answering the question, cause, I still have no optimal answer for it.
But, I really like when people start asking "what do you need this for". And, very rarely, the person who asked the question, really deserves this kind of question. I think not this time, but ok, this is not the issue...
Anyway, I will try to point out why some of us are convinced that
going from Activity A to Activity B(creating UI based on some data fetching) AND
going back from B to A(destroying all the created UI and/or fetched data in B) is sometimes a bad concept. Better solution would be to keep the stack as it is, so using something like finish() in Activity B, but keeping the Activity B in Pause state, so later when calling it again from Activity A - it just goes in onResume = nothing recreated in UI, no additional data fetching. The bonus of course is a fast and responsive UI, and the difference is really if you have a more complicated UI layout.
Just specify in the manifest for the activity as
android:persistent="true"
That should prevent your activity getting destroyed. To know more about this please refer to these below links which were answered by me
How to prevent call of onDestroy() after onPause()?
Prevent activity from being destroyed as long as possible
In the above posts I have explained in detail with a use case

Categories

Resources