Question about lifecycle methods definition - android

I learning Android about 6 month, and all this time i described Lifecycle methods like some kind of callback, which "trigerred" when OS change state or configuration.
Questions:
1) For example, User rotate the screen. As i think, Android invoce some interface and Activity runing it's code when callback come. I'm not sure about it, because i got throw documentation(Activity/Window/...classes) and i did't find this interface or smth like it. What's really happen when user rotate the screen?
2) For example, user push the button on his mobile app and create new Activity. Lifecycle methods will be called, but OS state or configuration was't change. It means, my definition of lifecycle methods is wrong. How to describe it correctly? Help me to understand what's wrong with my first definition.
I know about this link:
https://developer.android.com/guide/components/activities/activity-lifecycle
And there is a line:
The Activity class provides a number of callbacks that allow the activity to know that a state has changed...
But inside Activity class i see, for example:
#MainThread
#CallSuper
protected void onCreate(#Nullable Bundle savedInstanceState) {
and i have not see override word, so how Activity can implement it?
There is #CallSuper annotation, but parent classes(include Context) have no code connected with lifecycle. So it this real callbacks?

Not sure that I understand your question, because it is vague, but let me try to address the 2 specific examples:
1) For example, User rotate the screen. As i think, Android invoce
some interface and Activity runing it's code when callback come. I'm
not sure about it, because i got throw
documentation(Activity/Window/...classes) and i did't find this
interface or smth like it. What's really happen when user rotate the
screen?
In the usual case, when the user rotates the screen, a "configuration change" occurs. Android responds to this by killing off the currently active Activity. Android calls the "lifecycle methods": onPause(), onStop() and onDestroy() on the current Activity. Android then creates a new instance of the Activity and calls the "lifecycle methods": onCreate(), onStart() and onResume on that instance.
In case the application has declared that it wants to handle the configuration change itself (by specfying android:configChanges="..." for the Activity in the manifest), Android does not kill the Activity when the screen is rotated. Instead, Android calls the "lifecycle method": onConfigurationChanged() on the current Activity.
2) For example, user push the button on his mobile app and create new
Activity. Lifecycle methods will be called, but OS state or
configuration was't change. It means, my definition of lifecycle
methods is wrong. How to describe it correctly? Help me to understand
what's wrong with my first definition.
The "lifecycle methods" do not only refer to changes int he OS state or configuration. "Lifecycle methods" are also called to inform your Activity about changes in the state of the Activity itself. onCreate() is called to inform the Activity that a new instance of the Activity has just been created by Android and that the Activity should initialize itself. onResume() is called to inform the Activity that it is now the current Activity that the user will see (topmost Activity in its task and visible on screen). onPause() is called to inform the Activity that another Activity is going to become the current Activity. onConfigurationChanged() is called to inform the Activity that a configuration change has occured on the device (this can be one of many differnt things including: locale, screen size, screen density, screen orientation, keyboard presence, etc. There are many other "lifecycle methods" that are called by Android at specific times during the lifetime of an Activity.

Related

What we should do in onStart, OnResume, OnPause

Hi I have gone though activity lifecyle on many threads, but I could not find what we should do in onStart, onResume, onPause method of the activity.
In the onStart() method, you add code that's relevant at the beginning of the activity.
Let's say, you have an app that reads the temperature of the device's battery. You'll want to have an initial value, so as to show the user.
So in the onStart(), you'd add code that goes ahead and fetches the information you'd need, and displays it for the user, before your timer (for example) goes and reads the information a minute later.
The onPause() method is called before the application goes in to the background.
To stay with our example, in the onPause() method, you'd save the last recorded temperature to the device; so you can show a comparison when the user next opens the app.
The onResume() method is called when the application is brought back to the foreground (i.e.: you've gone to the task manager, and tapped on your app to show it again).
Again, staying with the going example; in the onResume() method, you'd go ahead, read your saved data, load fresh data, and show a comparison of the two in the application.
Then, when your timer ticks next, only fresh data will be shown.
Your question is a bit vague, so answer might not be super specific..
I would say there are no strict "rules" around what we should do in corresponding activity lifecycle methods.
In fact, you can do nothing there (just make sure you call super method if you decided to override those). I.e. your custom activity might not even override these methods - it will work just fine.
onStart, onResume and onPause methods are just hints to you about activity lifecycle change, so you can react accordingly, i.e. start/stop specific to your activity operations at the appropriate time.
For instance, when onResume is called it means that activity became fully visible to the user, so you might want to start some animation (if necessary)
Again, you are not obligated to put any code in there.
Usually most of the operations are performed within oncreate and onresume.
However for your info let me brief it out,
Onstart- this is called after Oncreate, once activity is visible to the user, if you want to perform some operations before the visibility do it in Oncreate, because most of codes should be operated before user views the activity.
OnResume-Be cautious on Onresume is it is quite tricky it will be called whenever you activity is brought to foreground.
Onpause-Called before Onresume, codes wont be executed here, so strictly avoid adding codes in Onpause instead add inside Onresume.
Hope it helps,

Activity onStart() not called when resuming an recreated activity from a stack

Long story short: I am currently working on a small android game. One feature is being able to change the app theme. When the user changes the theme, an event is broadcasted throughout the app and all active activities call recreate() to apply the new theme.
The problem:
Let's say there is a stack of activities: A, B, C. All activities will receive the event in the order they were opened and call recreate(). These are the lifecycle events that will get called (in order):
Activity A will call onDestroy(), onCreate(), onStart(), onResume() and onPause()
Activity B will call onDestroy(), onCreate(), onStart(), onResume() and onPause()
Activity C will call onPause(), onStop(), onDestroy(), onCreate(), onStart(), onResume().
Note that neither activity A or B called onStop(). When those activities are being returned to (eg. back button press), they will not call onStart() when they become visible, but will call onResume(). This is contrary to what is stated in the activity lifecycle documentation.
The question: Is there something I'm doing wrong here? Is there another way to restart all activities in an application without messing up the activity lifecycle?
I think you are taking the wrong approach here. You should not use the framework calls in order to change your theme. The issue you are having is that you are not calling onStop as the framework would, but even so...
The primary reason your approach is incorrect is that Android may have already destroyed an Activity if it is not visible. So sending events to it that call framework methods is not only unnecessary at that point, but it could result in unpredictable states and behavior. Could even cause a crash.
For changes to your theme or any UI component, you should handle that in onResume - in other words handle changes to the UI elements when the user returns to the Activity. One option for doing this is passing flags through startActivityForResult.
Better, make your theme selection persist using sharedPreferences (or using another method) and then read from that when the Activity is resumed. This would ensure the proper theme is selected regardless of how the user gets to the Activity.
EDIT:
Note that the Activity framework methods are public not because they should be accessed at any time or by other classes, but because that is required for them to be implemented in your app. They are not intended to be invoked outside the framework.
You should note that in the official documentation for Activity none of the methods you are calling are listed as "Public Methods" (http://developer.android.com/reference/android/app/Activity.html#Activity()). You are using them in an unsupported way. However, I only point this out to make you aware of it and that it is not a generally accepted approach to solving this problem.
This is exactly in line with the documentation.
http://developer.android.com/training/basics/activity-lifecycle/starting.html
If you look at the chart, onResume gets called when returning to an activity no matter what but onStart doesn't.
if you want to change UI related component then you must use OnResume method instead of recreating all activities. like following.
#override
onResume()
{
textview.setText("Change text When activity resumes");
}
Colleagues above responded very well.
The behavior you reported. The onstart and onResume not be called. I've watched it happening to Hot Code Swapping. It is worth stopping the application and call the rebuild.

Getting around onDestroy being called on orientation change?

I have a stock Nexus 5 running 4.4.2 (using ART if it matters) and I've found an interesting scenario. I have this as my onDestroy():
#Override
protected void onDestroy() {
super.onDestroy();
t.setText("onDestroy");
t.show();
}
It's a GPS oriented app so I'm up and walking around. I am using the technique mentioned in this question to show a lot of debug toast messages.
Anyway, when I rotate my app, the toast appears. I understand that the activity is destroyed and recreated for the new orientation, but how can I know what's really going on? How can I tell when my app is REALLY getting destroyed and not just being rotated? Similar to this question, I want to log out when a particular activity is destroyed.
Since Honeycomb, the isChangingConfigurations() method can be queried to check whether the Activity is being recreated due to configuration changes. Alternatively, the isFinishing() method can be queried on any API level to check whether the Activity is actually being finished, or is only being destroyed temporarily by the system.
As far as I can determine, the two methods should always return mutually consistent results in practice. The only point where they might have diverged is when the system kills the process to clear memory, but there are no callbacks or interaction with the app at that point.
The documentation of the onDestroy() method mentions the use of the isFinishing() method:
Perform any final cleanup before an 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.
You can put it in a fragment with setRetainInstanceState(true) set. Place your code in the onDestroy() method of the fragment. Then, the fragment will not be destroyed on orientation changes.
First of all, you should not use onDestroy() to do anything because its not guaranteed to be called. I would put things on the onPause() method; I wouldn't even put things in onStop().
Also, Im not sure why you want to log out a user when they navigate away from the app. I would rather implement some kind of timer on the app or server to log out after x time.
Now, the answer lies in the documentation: http://developer.android.com/reference/android/app/Activity.html#ConfigurationChanges
You might want to override onConfigurationChanged so that your activity is not restarted.
I found a couple of solutions which are really just patterns to detect when the screen rotates. Alternatively, you can determine that the device was actually destroyed by checking some static data member to see if it was initialized or not.
Configuration changed solutions:
The first one involves handling all of the configuration changes in the onConfigurationChanged callback.
"Note that this will only be called if you have selected
configurations you would like to handle with the configChanges
attribute in your manifest."
The second involves listening for Display.getRotation() which returns a Surface.ROTATION_* object. Which is the new orientation of your screen relative to the natural state of the device orientation.
Again, you can use the configuration changes along with the static member.
Add ConfigChanges.UiMode flag to the ConfigurationChanges attribute for your MainActivity class, and this solves the problem.
More details: Android Launcher "OnDestroy" gets called twice

Setting flag in onSaveInstanceState() to determine exit type in onDestroy()

For online games, it would be great to know if an Android Activity's onDestroy() is only called because Android is going to re-create it (e.g. device rotation) or if the user opted to exit the game.
My plan was to set a flag in the Activity's onSaveInstanceState() when Android is probably re-creating the Activity:
private boolean mDestroyedForReCreation;
...
protected void onSaveInstanceState() {
...
mDestroyedForReCreation = true;
}
If you did this, you can check mDestroyedForReCreation in onDestroy():
If the flag is set (true), don't dismiss the user from the online game.
If the flag is not set (false), dismiss the user from the online game as he did voluntarily exit the game.
Is that a correct approach? And if yes, is it recommended or is there any better solution? I hope so because I don't really like that solution ...
I suggest you to remove such kind of game logic from activity's life cycle. Create a Service. If no one binded - all activities are dead. Is someone binded - keep working.
If you do not want to create service, you can use onRetainNonConfigurationInstance method. Here is example.
You should use onRetainNonConfigurationInstance because it is called by the system, as part of destroying an activity due to a configuration change, when it is known that a new instance will immediately be created for the new configuration. onSaveInstanceState called when android going to kill activity and maybe restore it sometimes or maybe not ).
You can simply avoid restarts on rotation by handling this configuration changes by code. You can do this in your Manifest.xml like this:
<activity
android:name=".MainActivity"
android:configChanges="orientation|screenSize|keyboard|keyboardHidden"
android:label="#string/app_name" >
So your app won't restart on rotation and if the keyboard opened/closed.
I think this solution is much simpler.
In this case you almost don't need to handle onSaveInstanceState() for exiting, except you start another intent/activity where you need to save your game state. Note that a phone call will also interrupt your code. I know some games with funny bugs where the time is resetted but not the score.
I would just simplify the whole thing, and set a flag that is toggled when the user exits the game, something like:
void exitGame() {
mUserExited = true;
finish();
}
(Or you might need more logic if you need to destroy multiple activities)
Then check the flag in onDestroy().
Whatever logic you have about configuration changes (rotation, etc.) will have nothing to do with the exit game flag.
Also, remember that the 'back' button's default behavior is to finish() the current activity (if nothing else is above it) - that won't count as an "exit" in this case. The behavior here is up to you.
Activity has a method called isFinishing() that is probably what you are looking for.
See: https://stackoverflow.com/a/9621078/445348
If you need to know this, you should consider handling rotation and other configuration changed events yourself rather than letting the system do it. If you set in your manifest that the activity handles configChanges, it will call onConfigChange when it rotates rather than destroying and recreating the activity. A large amount of apps do this, the whol destroying and recreating on rotation thing Android does is absolutely retarded.
onRestoreInstanceState() will be called if when it is restored /recreated , if the activity if killed by android it saves its activity UI state and some values you can override onSaveInstanceState
but because onSaveInstanceState() is not guaranteed to be called, you should use it only to record the transient state of the activity (the state of the UI)—you should never use it to store persistent data. Instead, you should use onPause() to store persistent data (such as data that should be saved to a database) when the user leaves the activity. Also onRestart will be called after onStop() when the current activity is being re-displayed to the user. So probably you can save your state in onPause / if onRestart is called it is like it is being re displayed , while if onCreate is called without onRestart it is recreated . Other solution is to use singleInstance and override method onNewIntent which is called if activity is not destructed but like restarted on a new intent .

Determine whether Activity was closed or re-drawn

When using the onPause method in the Android SDK, that code is run whenever the Activity was re-drawn (Such as rotating the device). Is there a way to detect whether the Activity was actually paused (Such as a new window popping up) or if the Activity was actually just re-drawn?
Actually if you look at the life cycle of an activity, when the device is rotated, the activity is restarted, so after onPause(), the activity goes through the complete restart cycle (onStop() and onRestart() are also called), so in this case you can set some value depending on what functions were called, or check the device's orientation.
Also when the activity goes into background, onPause() is called, and when the activity is no longer visible to the user, onStop() is called, which are due to specific reasons, the application can check that by setting some variable. For complete understanding, study the activity life cycle (Alternate Link)
But why do you need to know what happened to the activity? By overriding appropriate functions and providing proper layout resources, you do not need to know what happened in most cases.
For orientation, you can also get the orientation using getRotation method.

Categories

Resources