I know that finish() returns your activity back to your previous activity. Now I am curious if we are able to accomplish the opposite meaning forwarding back to the next activity that you backed off without doing an Intent. This is just a curiosity question.
Is this possible?
No. The "next activity that you backed off without doing an Intent" was destroyed by a call to finish() when the user pressed BACK, so you cannot return to it.
No, that is not possible, once you run finish() (or press back) on an activity it will be poped from the activity stack and al its content garbage collected, only way to reach if again is by starting it with and intent.
Short answer: No, because The activity that finish()ed was destroyed.
Long answer: From the Activity Documentation
onDestroy() - The final call you receive before your activity is
destroyed. This can happen either because the activity is finishing
(someone called finish() on it, or because the system is temporarily
destroying this instance of the activity to save space.
Calling finish() doesn't actually guarantee immediate GC on the activity, but it will be made eligible soon after a call to finish(). You can assume that anything in the activity instance is gone if it wasn't persisted. Don't hold references to Activities that Android says should be killable, per Activity Lifecycle and Avoiding Memory Leaks, this is not a way to get around this, and is a Bad Idea(tm).
You could override OnDestroy() and check isFinishing() if you'd like to store the activity history in your application, so that you can manually implement something like "forward" functionality, but in general it's better practice to do something like that in onSaveInstanceState().
NO,because once you call the finish() method,it will destroy that corresponding activity.The only way to accompanish your task is by using an intent.
Related
I wrote a game, and in logs from market i sometimes see following pattern:
06:02:13:835|INFO|1|MainActivity|MainActivity#2.OnCreate
06:02:13:932|INFO|1|MainActivity|MainActivity#2.OnStart
06:02:14:010|INFO|1|MainActivity|MainActivity#2.OnResume
...
06:09:27:688|INFO|1|MainActivity|MainActivity#2.OnPause
06:09:28:895|INFO|1|MainActivity|MainActivity#3.OnCreate
06:09:29:159|INFO|1|MainActivity|MainActivity#3.OnStart
06:09:29:319|INFO|1|MainActivity|MainActivity#3.OnResume
06:09:29:551|INFO|1|MainActivity|MainActivity#2.OnStop
06:09:29:596|INFO|1|MainActivity|MainActivity#2.OnDestroy
MainActivity instance #3 is created and started before MainActivity instance #2 is destroyed. What does this pattern mean ? Why does new instance start before previous has been destroyed ?
Obviously i don't create activity by hand. Users simply start game by tapping icon(at least i hope so).
Activity has singleTask launch mode.
Thank you!
The onDestroy callback is not guaranteed to be called. From the docs:
onDestroy() = The final call you receive before your activity is
destroyed. This can happen either because the activity is finishing
(someone called finish() on it, or because the system is temporarily
destroying this instance of the activity to save space. You can
distinguish between these two scenarios with the isFinishing() method.
Suppose your application has two activities. Then this would be the life cycle
onDestroy will be called if you explicitly call finish(); yourself or like the example if you press Back button because pressing back key actually provokes finish() method on your activity, and it causes your activity to be paused->stopped->destroyed
I have 2 activities. Main Activity A & Activity B
I do not want Activity A to destroy. I am starting Activity B in a new task.
public static void startActivity(Class<?> startClass) {
Intent intent = new Intent(Constants.getActivity(), startClass);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Constants.getActivity().startActivity(intent);
}`
Constants.getActivity() returns the Context on current activity
startClass is the either activity "A" or activity "B"
Thing is they create/destroy the activities and they leak. Am I doing it wrong? How can I start activity "B" from activity "A" and vice versa keep them both in background when I dont need them.
First of all, what are you trying to do? You should always separate things you want to do in the background from your UI. Think of your Activities are simply a container to show the UI, everything else can be stored and restored from persistent storage or savedinstance bundles.
It is very crucial that you understand the difference between Activity lifecycle and Service lifecycle here.
I'm going to refer to my answer from another question here:
Your app will be in the background, onResume and onPause will both be called, provided that the OS have enough memory to keep the new app and all the old apps.
If you have a long running process that you need while the user not looking at it, use a service.
If you need the user to return the app in the same state, you need to do the work in onResume and onPause to save the state information and initialize your UI again when the user comes back. If you are really worried that it can get killed (well, it shouldn't lose the bundle I think), you can store them in SharePreferences for your app.
If you want to know when the app returns from that specific share intent, use startActivityForResult
You cannot keep an activity "alive" as you said. When an activity is paused, Android system is always able to claim its memory and unload it, at any time.
But if you want to switch from A to B, then maybe A and B can be different views inside a single activity. Maybe you'll want to have a look at http://developer.android.com/reference/android/widget/ViewFlipper.html
When you use tasks, cleanup is very important. You need to cleanup all tasks in the activity. readthis
If the activity does not have a lot of crazy initialization, just use finish and onCreates. Else be aware that onResume will be called often as you switch between activity's. Cleanup will be crucial here. If you dont cleanup, its possible one of your activities (with dead object reference from the other cleaned up activity) may come back up from the activity stack and throw exceptions. Its very difficult to debug this kinda exception.
I've read several posts that describe the difference between onStart() and onResume(): onStart() is called when the activity becomes visible, onResume() is called when the activity is ready for interaction from the user. fine.
I've always just added code to onPause() and onResume(), and never bothered with onStart() and onStop().
Can anyone give some concrete examples of what you might do in onStart(), vs. onResume()? Same goes for onStop() and onPause(), how is onStop() useful? I must be missing something fundamental here.
onStop() will (for example) be called when you leave the activity for some other activity (edit: almost. see commonswares comment about dialog themed activities).
For example if you use startActivity() in activity A to start activity B. When you press back in activity B you will return to activity A and onStart will be called.
This differs from some of the reasons onPause might be called without onStop being called. If for example the screen times out or you press the standy button onPause will be called, but probably not onStop (depending on memory available and whatnot), so it is a "lighter pause". onStop will be probably be called eventually even in this case, but not immediately.
Ok, but what's the use
Often there is no specific use, but there might be. Since your activities will keep its memory state on the stack even after you start some other activity, that stack will increase with the number of activities started (height of the stack).
This can lead to large memory usage in some applications. After a while the framework will kick in and kill some activities on the stack, but this is rather blunt and will probably mean a lot of states to be retained when returning.
So an example use for onStart/onStop is if you want to release some state when leaving an activity for another and recreate it when you get back.
I have used it to set listadapters to null, empty image caches and similar (in very specific applications). If you want to free the memory used by visible views in a listadapter you can recreate it in onstart and let the views be picked up by the gc. This will increase the likelyhood that the rest of the memory state of the activity will live on.
Some resources can be deemed good enough to save while the activity instance is alive and some only when it is on the front of the stack. It is up to you to decide what is best in your application and the granularity of create/start/resume gives you that.
onStart() works after onCreate() ended its task.
It's a good place to put a broadcastReceiver or initialize some state about the UI that should display consistently anytime the user comes back to this activity.
onResume() works when you come back to your Intent or Activity by pressing the back button. So onPause will be called every time a different activity comes to the foreground.
i think that your question is pretty explained here on the doc : read about the Activity Life Cycle
I have an Android activity we'll call A which has a button and another activity B. When the user clicks the button in Activity A, I'd like to finish A (let both onStop and onDestroy finish running) and then start up the instance of B. When I put a finish() and startActivity() call in the button click listener, the instance of B starts up before the old instance of A finishes. Can someone help me figure out a way to do what I'm looking for?
What you are looking for is not possible and actually is against Android's activity lifecycle implementation.
Correction
It is possible with android:noHistory="true" tag in your manifest, but for what you are trying to do it seems wrong (read the EDIT)... Messing with the activity stack makes a non intuitive application!
Android OS doesn't let you control when activities will be removed from memory (or killed), and therefore all these fancy "Task killers" are so popular (DONT use them, they only make things worse).
When your activity's onStop() is being called, the activity stops completely, and it just hangs in your memory, but that's fine...
If you want to reset the state of activity A, or close the app when exiting activity B, just create a set of rules in both onResume() and onStop(), you can do everything you wish by creating a set of rules in those functions.
for example: have a boolean in activity A that turns true just before calling activity B,call finish() on your activity A's if this boolean is true
I suggest that you take a look at Android's Activity lifecycle diagram, and make sure that everything you do follows the best practice.
EDIT
I saw your comment, it seems like you are trying to create things that are already in your memory, don't recreate them, it's a waste of CPU time, memory, and battery.
Instead, create a static class with a singleton that will hold all your shared data !
I believe you're looking for
onPause()
which is what gets called when the activity is sent to the background. You can do whatever cleanup you want in there. onStop should only be called when a user is exiting out of your program (or launching another one)
onPause is a better place to do this cleanup. See the Saving Persistent State section of the Activity doc.
When an activity's onPause() method is called, it should commit to the backing content provider or file any changes the user has made. This ensures that those changes will be seen by any other activity that is about to run. You will probably want to commit your data even more aggressively at key times during your activity's lifecycle: for example before starting a new activity, before finishing your own activity, when the user switches between input fields, etc.
While I'm not definite that your cleanup is for user changes, the bold sentence above implies that onPause will complete before the next Activity is created. Of course that probably implies that you'll have to move some setup to onResume...
Alternatively, you could move all your cleanup code to a method, let's just call it cleanup and then just call it before you start activity B. You'll have to put in appropriate guards for your onDestroy cleanup too of course.
override finish() method.
implement cleanUp() method.
create boolean isClean=false in the activity
in cleanUp() write your clean up code.
call cleanUp() in your finish()
check for isCleaned in finish() or in cleanUp() if its true then ignore the clean
now before you start B , call cleanUp() and set isCleand=true
after you call B , call finish()
Start activity A
from inside A startService(c) and finsh A
from inside the service , start Activity B
According to the android Activity Lifecycle, the only callback guaranteed to be called (if an activity ever leaves the Running state, which is typically expected) is onPause().
So, I must assume that there are scenarios in which it makes sense to implement onStop() and onDestroy() although they are not really guaranteed to be called.
I understand that onStop() should be implemented when it's possible for an activity to return to the Running state via the Stopped state (why would it do that instead of returning directly is a different question).
But the need for onDestroy(), when I can place all cleanup/state-saving into onPause(), is unclear to me.
Can you describe a real-app situation (i.e. not analogy to driving a car etc.) in which it would make sense to implement onDestroy()?
onDestroy will be called if you explicitly call finish(); yourself.
Your main activity calls startActivityForResult on a map activity.
Map activity with a LocationListener, the user clicks the map and selects say a local restaurant.
The activity then , sets up some extras to be sent back to your main activity, it then explicitly call's finish(); on itself and in the onDestroy kills the LocationListener and other variables you had invoked.
Just found this in the docs
onDestroy() = The final call you receive before your activity is destroyed. This can happen either because the activity is finishing (someone called finish() on it, or because the system is temporarily destroying this instance of the activity to save space. You can distinguish between these two scenarios with the isFinishing() method.
Can you describe a real-app situation
(i.e. not analogy to driving a car
etc.) in which it would make sense to
implement onDestroy()?
When you want to capture a configuration change. It's all in the SDK:
http://developer.android.com/reference/android/app/Activity.html