Why Activities are designed where it allows to call onDestroy() after onCreate()? - android

One scenario where an activity does not go through its full life cycle is where there is a requirement to make a decision (may be via an if condition inside onCreate()) and kill the activity immediately by calling Finish() inside the onCreate() method itself. onDestroy() is called after onCreate() when this happens.
This clearly is a deviation from Activity lifecycle. My question is
1) Why is such behavior allowed by Android? Any possible reasons for this?
2) Are there any other ways that this kind of decision making functionality be implemented? Are there any built in facilities like say a widget or background method who does this for the programmer?

Activity is not going through the documented life cycle of onCreate() OnStart() onResume() onPause() onStop() and then onDestroy() is bypassed to make it onCreate() and then onDestroy() without other methods
It is going through the portion of that lifecycle that is appropriate for the situation. Quoting the documentation: "The visible lifetime of an activity happens between the call to onStart() and the call to onStop()". Hence, in situations like this, where the activity is never visible, there is no need to call onStart(), onResume(), onPause(), and onStop().
From a programmer's perspective these kinds of exceptional cases always add to complexity of learning something
These sorts of complexities are commonplace in software development for pretty much any platform and environment.
So, I wanted to know if there was any valid reason behind allowing something like fall to finish() inside onCreate().
Nobody but you knows what you would consider to be "any valid reason".
Most likely, this as an optimization path, to save on CPU time, battery, and possibly some memory, by skipping unnecessary work. Please bear in mind that Android was designed around hardware from a decade ago, where mobile CPUs had ~1% of the processing power of today's devices, let alone devices that may arise in the future.

When you navigate from one activity to another and you don't need the first activity to be living anymore (like a splash screen), you might be calling the following from somewhere in the first activity:
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);
finish();
And if you don't call that finish method and allow that splash screen to be in resumed state. What happens when you press the back button from your SecondActivity? You will see the splash screen again! Imagine how horrible that would be. The intention of this Android framework is not to make you pass through all the lifecycle methods of an Activity, but to provide you whatever facilities that you need in your app. I think this example can help you understand why such behaviour is not allowed by Android.

As understood from other answers for this question, activities are designed in such a way that they need not go through or invoke all the methods in its life cycle.
Common situations where programmers design activities that do not pass though its full life cycle are like, requirement to display a splash screen. Another requirement is for any any task that does not require a UI at all, and finish() is invoked inside the onCreate() method itself. In this case, as the question suggests, onDestroy() is called immediately after onCreate() without invoking other intermediate methods of activity life cycle.
However, I am not sure about android providing any widgets for any such specific tasks, but it always makes sense to perform any such non-UI tasks in a service rather than an activity whenever possible. It is up to the programmer to decide what is apt for a given requirement.

Related

Confused by asynchronous mechanism

I am confused by the fact that android is multi-threaded. If the code of a particular activity method is executing, can it be interrupted in the middle by onPause(), onStop() or onDestroy() or by another method like the onPostExecute() of an asynctask?
Edit 1
This question is not about activities life-cycle. What i am really asking is if the onPause() method can interrupt the onClick() method (just an example) and i would like to read more about how exactly android manages activities, calls their async methods etc...
Edit 2
Ok, it seems that i have found the relevant information i needed in the developer docs (don't know if it is explained better somewhere else): Threading Performance:
Internals
The main thread has a very simple design: Its only job is to take and
execute blocks of work from a thread-safe work queue until its app is
terminated. The framework generates some of these blocks of work from
a variety of places. These places include callbacks associated with
lifecycle information, user events such as input, or events coming
from other apps and processes. In addition, app can explicitly enqueue
blocks on their own, without using the framework.
It states that callbacks relative to activity lifecycle, user events such as input and other code are all managed using a "thread-safe work queue". This is central to understanding Android asynchronous programming. It explains a lots of things, such as why onClick() will be never be interrupted by activity onPause(), or why onClick() will be never be interrupted by a runnable posted using a Handler object (allocated in the main thread). So, for example, the onPostExecute() of an AsyncTask cannot interrupt the onClick() method (or onStart(), onResume(), onPause() etc...). As a novice android programmer, it was a bit confusing at first.
According to your question, I think you need to understand basic about Android Application's life cycle.
Basically, the life cycle deals with the state of application in different different situation.
Like what will be state when application goes, in foreground or background and all that So These cycles state that you had mentioned like onPause(),onDestroy(), onStart(), onCreate().
Now talk for AsynchTask(), If you want to execute long running process like downloading image or listening musing or any other then we will use BackGround services. So don't get confusion between life cycle method and background services. .
Third, App will close only some rare condition like if memory is not sufficient or some other fatal issue occur in App then only it will terminate.
So, findings are that Thread is meant for long running process and Activity Life Cycles method are meant for various activity state
Please follow this tutorial and I hope you will get clarification
This is a good question to ask I think. However, Here is my understanding:
When an Application starts, a Dalvik Virtual Machine (DVM) is assigned to it and works separately. So no two Applications interrupt each other as each of the application is managed by separate DVM.
Coming to Activity, it is a component of Android and runs on main thread. Android OS manages priority level to it's components. It gives high priority level to Activity, Services and may be other component(s). The OS maintains the non interruption behaviour of main thread.
Further when you run an AsyncTask, it is a long running task in background but dependent on Application context. So the OS does not guarantee to manage it.
Now regarding activity life cycle. As #nihal_softy said, activity has it's own life cycle which start from onCreate() and encounters onStart(), onResume(), onPause(), onStop() and onDestroy(). You can call these methods from anywhere of your Activity or from an AsyncTask and it will called but does not mean that the Activity will go in background or will destroy. In a simpler word, if you call onPause() from an AsyncTask, it does not mean that the Activity will be sent to background (if in foreground). Because when an Activity will go in background then it calls it's life cycle methods such as onPause() and onStop() as callback. But converse is not true.
I hope my understanding will help you to get the answer.

Is onPause() or onStop() called even if phone dies due to lack of power?

If I, for example, need to keep some very important data which the user can edit within my app, should I need to save them every time user changes such data or is it ok if I would save it within onPause(), onStop() or onDestroy() methods?
Can somehow application end without any of those methods calling? (For instance when battery runs out)
This certainly can't be done in onDestroy().
According to the documentation:
There are situations where the system will simply kill the activity's
hosting process without calling this method (or any others) in it, so
it should not be used to do things that are intended to remain around
after the process goes away.
So yes, the application can end without calling any of the lifecycle methods.
In that scenario when the phone is shutting down, you can use the ACTION_SHUTDOWN Intent.
More info here. For all other cases onPause should do the work. Even in the link provided, there is a statement that onPause will be called if the app is in FG.
Apps will not normally need to handle this, since the foreground
activity will be paused as well.
However, if it is not so expensive operation, I would go with saving data after edit.
As per the documentation of Android activity life cycle, onPause is called when an activity is going into the background, but has not (yet) been killed.
Hence, in most Android documentation, and sample codes you will find onPause is used for saving any persistent state the activity is editing, to present a "edit in place" model to the user and making sure nothing is lost if there are not enough resources.
So in your use case, all you need to do is implement onPause for your Activity and write a code to Save the activity state (EditText content or any other ongoing user interactions). Android system will save the activity state which you can always get back in onCreate of your Activity when android launch your activity next time.
in this case please verify your phone activity via debug interface , some of phones are terminate your application this is force quit.

How to detect the completion of launching an app?

In Windows Phone, there is Application.LoadCompleted Event for detecting the finish of starting an application.
Note the finish means that users are able to interact with the app.
Is there similar API on Android? Any other approaches to achieve this?
after onResume() gets called it means the user can start interacting with your app. Consult this document for more information
You can override onCreate method of main Activity.
It depends what you mean by 'finished starting'. Activities, including the main activity, can be created and destroyed - and therefore onCreate() called - multiple times, for example (in the default behaviour) when the device orientation changes. onResume will be called even more often, for example every time the activity comes to the foreground. Then there's onStart(). See the Android developer docs to see when in the lifecycle each is invoked. It's true that the first time onResume() is called on the main activity will be when the app is fully started, but you won't know it's the first time without storing state somewhere outside any activity, for example on a singleton, or by subclassing the Application class, which is not something especially encouraged, as far as I can tell.

details of Android application components destruction and recreation

Could someone push me in the direction of some concrete, trustworthy (and preferably concise) information on the following:
The order in which components are destroyed and (where applicable)recreated by the system
(Fragment, Activity, Activity's Threads/AsyncTasks/Timers,
static data(when are classes unloaded?), Threads/AsyncTasks/Timers in other classes, host
TabActivity, ActivityGroup, bound local Services, Application, process)
both when the app is in the background, and in the foreground.
At which points the destruction can stop (what states can be encountered
upon return to the app - like "everything including the Application object
destroyed, process alive"?
Is it possible (without modifying Android) to programmatically cause the same kind of destruction
ourselves, so that it is indistinguishable from when the system does it, or is a separate mechanism needed for when we ourselves choose to free memory (triggered by onLowMemory)?
Reliable reproduction steps of all scenarios from 1) (would junit.framework do? I haven't investigated that) ?
"If the user leaves a task for a long time, the system clears the task of all activities except the root activity. When the user returns to the task again, only the root activity is restored": is this aside from the process/component lifecycle/destruction, or tied to it?
I have read various sources give pieces of information, often incomplete and misleading, sometimes incorrect.
I admit, I have skimmed over some parts of the documentation, so i may have missed or misunderstood something.
[EDIT] To avoid misunderstandings: What I am asking about is Android destroying components to free memory, bypassing Activity.onDestroy.
When I put the app in the background and return later, the one of these sequences will occur:
onPause, onStop, onRestart, onStart, onResume
onPause, onStop, Application.onCreate, onCreate(notNull), onStart, onResume
[EDIT2]
Bounty started. Need reliable info on: Activities, Fragments, Application, bound (potentially remote)Services, process.
Partial/full destruction scenarios. See 1st point.
This is what my experience, and that of devs I've asked, seems to suggest:
Fragments are not autodestroyed.
non-visible Activities on the app's stack can be autodestroyed in any order, and in any number.
destroyed Activity's (or any other class's) Threads and statics remain untouched until Application is destroyed.
TimerTasks: haven't tested.
bound local Services: destroyed somewhere between the destruction of the last binding Activity and of Application.
Application is the last thing to go within a process, and "goes" along with all Threads.
the process can exist for a long (20+ minutes) time after the destruction of the Application object, unless you have an automatic task killer.
Activities under TabActivity or in ActivityGroups are not autodestroyed, but go all at once if the container is destroyed.
Example: a TabActivity with ActivityGroups under tabs. All Activities live. Another Activity is started, fullscreen. The TabActivity with everything in it is now eligible for destruction by Android, all at once or not at all.
NO.
If you destroy an Activity manually, it goes through the entire lifecycle and doesn't pass a Bundle to onCreate when started again.
Also, onLowmemory is unreliable - even with small allocation steps, it might never be called before OutOfMemoryError is thrown.
NO.
Despite the autodestruction/restoration being such a major feature in Android, there isn't any way to test such scenarios.
This is probably related only to whether the process still exists or not. If it does, Android will attempt to restore the old Activities. If not, it's a clean restart.
The above include some assumptions.
I am still waiting for someone to confirm it and supply some docs (guarantees not dependent on the current implementation of classes).
Please, PLEASE correct me if any of this is wrong.
Edit: The above information may be out of date, it was tested on Android 2.1-2.3
Credit for this goes to hackbod for writing it here(read the whole answer), and to CommonsWare for linking in a comment.
In short: All the docs, rewritten many times, continue to lie to us. They're not misleading, they just give us untrue information. Unless you're using Fragments (dunno if support v4 counts, too), Android frees memory by killing the whole process, or does nothing.
Of course, this does not address everything:
Point 4 of the question
Why I frequently saw onCreate(notNull) on pressing Back on an Activity stack with Activities handling all config changes (Android 2.3.7)
How this relates to the widely accepted belief that onPause is the last call you are certain to get, and onStop may never get called (how, then, can the app go to the background, to be killed?)
We're getting somewhere, though.
Well, my friend,
I guess you'll have a lot of trouble in your research. Basically because you're talking about two black boxes: the Dalvik garbage collector and the android heap manager. I would say that you cannot trust that android will follow any order of object destruction. But, you can trust that this lifecycle is going to be followed [Programming Android, 2011]:
Activity Lifecycle:
onCreate() - Called after the instance of the activity has been created for the first time
onRestart() - Called after an activity has been interrupted, just before the onStart();
onStart() - Called when the object activity and their visions become visible to the user;
onResume()- Called when the object activity and their visions become interactive to the user;
onPause() - Called when a different instance of the activity is going to get visible and the present activity ceases to interact with the user
onStop() - Called when the activity is no longer visible or is not interacting
onDestroy() - Called when an activity instance must be destroyed and it's no longer needed.
Fragments have different lifecycles including methods onAttach, onCreateView and onActivityCreated .
But, why do you care about the objects order of destruction? I can't see no reason for you to monitor such events, but if you really need, learn more about the garbage collector.
The ActivityManagerService#trimApplications()method remove any unused application processes if the application's current receiver is null, does not have any activity and service.
When it comes to activities, they will be only destroyed on on Destroy() until and unless developer manually calls the finish() function,
Fragment life cycle is a completely matched to its parent activity, so when parent activity destroys on on Destroy(), the fragments on Destroy() as well will be called.
Timer Tasks will finish their work and become candidates for garbage collection, once the activity creates them the task runs in its own thread, no relation with activity, even if the activity is destroyed, the task finishes itself....
This is not a complete answer but what I would recommend is that you place toast messages in each of these methods. Add in your own onPause(), onStop(), onResume(), etc. and inside put a line like this:
Toast.makeText(this, "onPause()", Toast.LENGTH_SHORT).show();
You cannot directly call these methods, however moving another activity to the top of the stack will of cause these methods on the existing activity to be called. One more thing to keep in mind is that onCreate() need not be called every time you start an activity. It really depends on how you start the activity, for example if you send this intent
Intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_SINGLE_TOP);
it will appear call onNewIntent() instead if it has already been created. In summary the best thing is just to watch the Toast messages. Also you really need to focus on using the debugger. Place a breakpoint on each method and you can see it. One thing I am sure of is that you cannot directly invoke these methods like onPause(). Also keep in mind that in general you don't know when onDestroy() will be called.

How much time can be taken inside onDestroy() before the activity is killed?

I know my question caption must have sounded really vague. But let me clear it out here.
Say I have an android application over a middleware stack. In onCreate() of my activity, I initialise my middleware modules.
In its onDestroy(), I must de-initialise the middleware. Now my middleware calls may take quite some time to process. So I want to know how much time the onDestroy() function has, and see whether my deinitialisation can take place within that time.
Is it reasonable to keep my de-init in the onDestroy()?
Also, suppose I initialise the middleware in onCreate() of activity A1. On a button click, activity A1 switches to activity A2. In low memory situations, the LMK will kill the activity that has not been in use for some time. In such a case, won't activity A1 be killed? When activity A1 is killed, will all instances I create in A1 also get destoryed?
Regards,
kiki
I believe you are rather confused to ask this question.
In order to get a good comprehension of what is happening, you should take a look at the lifecycle graphs that can be found on developer.android.com:
Activity lifecycle
Background service lifecycle
You will see that Activity.onDestroy() only gets called in the case of a controlled shutdown of the activity - something that happens extremely rarely, as the Android OS can kill your process in a variety of states without ever calling your onDestroy() method.
What and why do you need to de-initialize?
If you're worried about releasing resources, then most of them will get released anyway when/if your process is killed.
If you are worried about saving the user's data (your application's state) then you should override onSaveInstanceState() and onRestoreInstanceState()
If you really want an answer to your question, then here it is:
While it is running onDestroy(), your app has (probably) as much time as it would like to - the fact that it is even running onDestroy() means that the OS did not select it to be killed. But it will most likely not matter: for one, onDestroy will never be run in most apps, and if the OS changes its mind and decides that your app must die, it will kill it even if it is running onDestroy.
http://developer.android.com/guide/practices/design/responsiveness.html:
In Android, the system guards against
applications that are insufficiently
responsive for a period of time by
displaying a dialog to the user,
called the Application Not Responding
(ANR) dialog
The ANR dialog will normally pop up if your application is un-responsive for 5 seconds. As pointed out by jhominal, the onDestroy() method is probably not where you want to do your clean-up/save preferences/etc.
Regardless of where you choose to do this, be it onDestroy(), onSaveInstanceState() or in onPause(), I believe the general 5 second rule will apply. If what you're doing takes more than 5 seconds, the ANR dialog will show and the user can choose to force-close your app.
Edit:
If your application is in the background, it might be (probably?) that it is killed directly without the ANR dialog being displayed if you violate the 5 second rule. But I do not know this for sure, only assuming.

Categories

Resources