Android Architecture Components Lifecycle state - android

https://developer.android.com/reference/android/arch/lifecycle/Lifecycle.State.html
STARTED
Lifecycle.State STARTED
For an Activity, this state is reached in two cases: after onStart
call; right before onPause call.
As the above documentation says, I couldn't understand the rationale behind the STARTED state right before onPause call. Can someone please explain that?

Notice that the values in the Lifecycle.State enum do not include a PAUSED state. There are only five states: CREATED, DESTROYED, INITIALIZED, RESUMED, STARTED. These do not exactly correspond with the normal Activity lifecycle that we all know and love:
Also note the following from the Lifecycle class documentation:
ON_CREATE, ON_START, ON_RESUME events in this class are dispatched after the LifecycleOwner's related method returns.
ON_PAUSE, ON_STOP, ON_DESTROY events in this class are dispatched before the LifecycleOwner's related method is called
The execution of the onPause() is the closing boundary for the RESUMED state. At this point, the Activity is no longer considered RESUMED and it is certainly not DESTROYED. Since we don't have a PAUSED state it follows it must now be in the STARTED state. This is technically true, the Activity hasn't yet stopped but it is no longer resumed.

Related

android lifecycle event CREATED

If you follow the link https://developer.android.com/reference/androidx/lifecycle/Lifecycle.State.html#CREATED
you'd see that CREATED event is raised in two conditions
1) after onCreate (understandable )
2) right before onStop(wait what ?)
why would the lifecycle raise the CREATED event just before onStop ?
First of all, CREATED is not an event but an activity state. The given doc means after onCreate() called, activity is in CREATED (then became RESUMED after onResume() called). When the activity onStop() called, activity became CREATED again (CREATED but not RESUMED in this case).
Be careful, you're confusing states with events!
State (Enum values) :CREATED, DESTROYED, INITIALIZED, RESUMED, STARTED
also check this : https://developer.android.com/guide/components/activities/state-changes
"When a configuration change occurs, the activity is destroyed and recreated. The original activity instance will have the onPause(), onStop(), and onDestroy() callbacks triggered. A new instance of the activity will be created and have the onCreate(), onStart(), and onResume() callbacks triggered."
So given the possible states, CREATED is the one that fit best when onStop is called

Why LiveData still notify Activity which is in onPause state?

I have the following code in Activity
#Override
public void onPause() {
super.onPause();
if (isFinishing()) {
final LiveData<StickyNoteConfig> stickyNoteConfigLiveData = StickyNoteConfigRepository.INSTANCE.getStickyNoteConfig(mAppWidgetId);
stickyNoteConfigLiveData.removeObservers(this);
stickyNoteConfigLiveData.observe(this, stickyNoteConfig -> {
// Weird, I still can receive call back.
// I thought "this" is no longer active?
});
}
}
I feel puzzled that, Observer is still being triggered, although this activity is already in onPause state? According to https://developer.android.com/reference/android/arch/lifecycle/Lifecycle.State#STARTED
Started state for a LifecycleOwner. For an Activity, this state is
reached in two cases:
after onStart call;
right before onPause call.
May I know why it is so?
According to LiveData reference,
LiveData is a data holder class that can be observed within a given lifecycle. This means that an Observer can be added in a
pair with a LifecycleOwner, and this observer will be notified about
modifications of the wrapped data only if the paired LifecycleOwner
is in active state. LifecycleOwner is considered as active, if its
state is STARTED or RESUMED.
An observer added with a Lifecycle will be automatically removed if the corresponding Lifecycle moves to DESTROYED state.
Now, according to your situation here, LiveData receives updates for your observer (your activity) in onPause() method, because your observer is not already in DESTROYED state.
So LiveData is still active for receive updates according to these methods:
onActive() :
Called when the number of active observers change to 1 from 0.
This callback can be used to know that this LiveData is being used thus should be kept up to date.
&
onInactive() :
Called when the number of active observers change from 1 to 0. This does not mean that there are no observers left, there may still be observers but their lifecycle states aren't STARTED or RESUMED (like an Activity in the back stack).
You can check if there are observers via hasObservers().
So when does observer (your activity) gets DESTROYED state?
For default implementation of LifeCycleOwner indicates that activity gets it's DESTROYED state once onDestroy() method is executed & after onPause() it follows reverse order of LifeCycle state RESUMED -> STARTED -> CREATED -> DESTROYED.
Check this lifecycle graph.
Hope it helps !
https://medium.com/#hanyuliu/livedata-may-lose-data-2fffdac57dc9 has logs to explain this issue. And just like #Vairavan said,in pause state activity can be partially visible.
public enum State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;
public boolean isAtLeast(#NonNull State state) {
return compareTo(state) >= 0;
}
}
so, observer's isAlive judge according to isAtLeast(STARTED). when OnPause is called, activity does not become DESTROYED.
This becomes obvious when onPause and onStop is related to UI side effects. An activity is paused and not stopped if any part of the activity window is still visible. This could happen when another activity is shown on top of the paused activity as a dialog. In this case, more often than not, developers would like the paused activity's UI to still be updated even though it is only partially visible. LiveData's update in this paused state helps do that.
There are other cases like multi-window feature. One activity could be paused while the user is interacting with another app/activity in a different window. Paused activity could be a video playback with active updates and should be updated even though user is interacting with another app. Note that this implementation is changing from Android P for foldable phones where multiple activities/windows could be in resumed state (that is not the concern for live data updates anyways). https://android-developers.googleblog.com/2018/11/get-your-app-ready-for-foldable-phones.html
Normally, onPause (without onStop) will happened when a partially of screen is cover by other screen (eg: notification from other app, or open a transparent activity).
Because, whole screen is not cover, so we may see some part of the current screen.
Therefore, I think LiveData may still need to notify in on pause state to make sure user always see the latest data.
If user go to background, or navigate to other screen, then the whole of screen is cover, we dont need to update UI because user dont see it. So LiveData dont need to notify in onStop state
Helpful answers:
Android: Scenario where onPause is called but not onStop?
LiveData only updates app component observers that are in an active lifecycle state.
If anyone wants to perform any lifecycle-related work they must override onActive() and onInActive() methods.
eg:
public class StockLiveData extends LiveData<BigDecimal> {
......
#Override
protected void onActive() {
}
#Override
protected void onInactive() {
}
}
Important Line:
An observer added with a Lifecycle will be automatically removed if
the corresponding Lifecycle moves to DESTROYED state.

What's the best place to allocate your controller class in the Android lifecycle?

i use in my android projects the MVP pattern.
and therefore allocate the presenter in my activity that i am going to use.
in android there are 3 stages before the activity is completely active.
the onCreate, onStart and onResume, but what is the best place for allocating the Presenter class for optimal UI and Memory performance?
and the Presenter class should not leak memory.
Most of the time you should do it in onCreate callback. Everything should be instantiated here. Normally there is no reason to do it elsewhere, because you have the same presenter regardless of the Activity state. In some special cases, if you have to bind and unbind some kind of lister that your activity doesn't listen to events while in paused or stopped state, you can work with onResume and onPause but again, that just special cases. And most of the time you just call some methods on your already created presenter.
You should do it in onCreate(). But onCreate() is called only once while creating the activity, if the activity goes in pause state, it will resume the activity by calling onResume(); it won't call onCreate() again. So if there are some things which you have to check again and again then onResume() is the good place to do it.

Do member variables of an Activity retain values after onResume?

Is this safe to assume that when onResume is called all of the member variables native or objects in the activity are still valid ?
In otherwords is it possible that android cleans up any member of an activity under memory stress conditions and then ends up calling onResume ?
When onResume is called anything that was previously set in onCreate, onStart, etc will be there. However if the Activity is deleted due to memory pressure you may have to recreate old values in either onRestoreInstanceState or onCreate, either of which will be called again before onResume is.
I dont think the activity lifecycle guarantees the state will remain on calling onResume. The documentation states that you should reinitialise all components in onPause
https://developer.android.com/training/basics/activity-lifecycle/pausing.html#Resume
An excerpt from the above link:
When the user resumes your activity from the Paused state, the system calls the onResume() method.
Be aware that the system calls this method every time your activity comes into the foreground, including when it's created for the first time
As such, you should implement onResume() to initialize components that you release during onPause() and perform any other initializations that must occur each time the activity enters the Resumed state (such as begin animations and initialize components only used while the activity has user focus).

Android onStop/onDestroy - when might these be used?

Looking at the Activity Life Cycle diagram, I notice that onPause() and onStop() can both lead to the "process" being killed. This would require onCreate() to be called when the user wants to resume their application. The point being that onStop() is not necessarily called, nor is onDestroy(), but that onPause() may be the only event that the Activity may see. This being the case, onPause() must handle saving the application status so that the user can return back to it later, regardless of whether onStop() is called or not.
I can see onDestroy() being used to clean up Activity specific resources that would naturally be eliminated in a process kill action. Is there anything else that onDestroy() would be good for?
And what would onStop() be good for? Why would I want to override it for?
If I got your question right: It depends what you want to do with your application. Let's say you are programming application that uses GPS. In the onStop() which is called when the activity is no longer visible to the user, you can remove these requests. Or you can stop the some service if your application is running any. Or you can save preferences (not recommended, do it in onPause() instead), or you can close permanent connection to a server.....If I think of anything else, I'll add more...
If you have read the doc further, you'll see following:
Saving activity state
The introduction to Managing the Activity Lifecycle briefly mentions
that when an activity is paused or stopped, the state of the activity
is retained. This is true because the Activity object is still held in
memory when it is paused or stopped—all information about its members
and current state is still alive. Thus, any changes the user made
within the activity are retained in memory, so that when the activity
returns to the foreground (when it "resumes"), those changes are still
there.
However, when the system destroys an activity in order to recover
memory, the Activity object is destroyed, so the system cannot simply
resume it with its state intact. Instead, the system must recreate the
Activity object if the user navigates back to it. Yet, the user is
unaware that the system destroyed the activity and recreated it and,
thus, probably expects the activity to be exactly as it was. In this
situation, you can ensure that important information about the
activity state is preserved by implementing an additional callback
method that allows you to save information about the state of your
activity and then restore it when the the system recreates the
activity.
Summary: After completing onStop() Activity object is still alive in memory. And this will help the system to restore the activity.
Very basic example: consider you are showing your activity to user, and suddenly your friend calls you! Rest you can understand..
So now it it up to you that, which are the resources/objects/connections should be released on which event.
Another example would be to register and unregister a broadcast receiver.
Note that usually these things are placed in onResume and onPause, the difference is subtle though, onResume/onPause are called when the activity gets placed behind another activity, onStart/onStop are called when the activity is no longer visible in the screen.

Categories

Resources