Activities Flashcards
What is Activity in Android?
An activity is the entry point for interacting with the user. It represents a single screen with a user interface. For example, an email app might have one activity that shows a list of new emails, another activity to compose an email, and another activity for reading emails. Although the activities work together to form a cohesive user experience in the email app, each one is independent of the other
Key concepts of Activities?
- All activities can be entry point for an app
- One activity implements one screen in an app (Generally)
- Each activity is only loosely bound to the other activities
- Activities must be registered in app Manifest
- Must manage activity lifecycles appropriately
Different ways of starting activities
- Implicit Intent
- Explicit Intent
- By navigation controller (Android Jetpack Navigation Component)
Difference between implicit and explicit Intents
For example, an explicit request might tell the system to “Start the Send Email activity in the Gmail app”. By contrast, an implicit request tells the system to “Start a Send Email screen in any activity that can do the job.”
What is Intent Filters?
Intent filters are a very powerful feature of the Android platform. They provide the ability to launch an activity based not only on an explicit request, but also an implicit one.
So you can use activities from other app which are able to do things that you want.
Activity lifecycle callbacks and when system invokes them
- onCreate() - fires when the system creates activity
- onStart() - starts when onCreate() exits, activity becomes visible to the user.
- onResume() - system invokes this just before the activity starts interacting with the user.
- onPause() - system call this when loses focus from activity. Activity may be partially visible
- onStop() - system invoke this whet the activity is no longer visible to the user.
- onRestart() - the system invokes this callback when an activity in stopped state is about to restart.
- onDestroy() - system invokes this callback before an activity is destroyed.
For what is lifecycle callback?
Within the lifecycle callback methods, you can declare how your activity behaves when the user leaves and re-enters the activity.
For example, if you’re building a streaming video player, you might pause the video and terminate the network connection when the user switches to another app. When the user returns, you can reconnect to the network and allow the user to resume the video from the same spot.
In other words, each callback allows you to perform specific work that’s appropriate to a given change of state. Doing the right work at the right time and handling transitions properly make your app more robust and performant.
What can ensure good implementation of the lifecycle callbacks?
For example, good implementation of the lifecycle callbacks can help ensure that your app avoids:
- Crashing if the user receives a phone call or switches to another app while using your app.
- Consuming valuable system resources when the user is not actively using it.
- Losing the user’s progress if they leave your app and return to it at a later time.
- Crashing or losing the user’s progress when the screen rotates between landscape and portrait orientation
onCreate() lifecycle callback
You must implement this callback. On activity creation, the activity enters the Created state. In the onCreate() method, you perform basic application startup logic that should happen only once for the entire life of the activity.
For example, your implementation of onCreate() might bind data to lists, associate the activity with a ViewModel, and instantiate some class-scope variables.
This method receives the parameter savedInstanceState, which is a Bundle object containing the activity’s previously saved state. If the activity has never existed before, the value of the Bundle object is null.
Your activity does not reside in the Created state. After the onCreate() method finishes execution, the activity enters the Started state, and the system calls the onStart() and onResume() methods in quick succession
onStart() lifecycle callback
When the activity enters the Started state, the system invokes this callback. The onStart() call makes the activity visible to the user, as the app prepares for the activity to enter the foreground and become interactive. For example, this method is where the app initializes the code that maintains the UI.
The onStart() method completes very quickly and, as with the Created state, the activity does not stay resident in the Started state. Once this callback finishes, the activity enters the Resumed state, and the system invokes the onResume() method.
onResume() lifecycle callback
When the activity enters the Resumed state, it comes to the foreground, and then the system invokes the onResume() callback. This is the state in which the app interacts with the user. The app stays in this state until something happens to take focus away from the app. Such an event might be, for instance, receiving a phone call, the user’s navigating to another activity, or the device screen’s turning off.
When an interruptive event occurs, the activity enters the Paused state, and the system invokes the onPause() callback.
If the activity returns to the Resumed state from the Paused state, the system once again calls onResume() method. For this reason, 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.
Why use lifecycle components?
By using lifecycle-aware components, you can move the code of dependent components out of the lifecycle methods and into the components themselves.
Adding this logic into an independent, lifecycle-aware component allows you to reuse the component across multiple activities without having to duplicate code.
What is lifecycle component?
Lifecycle-aware components perform actions in response to a change in the lifecycle status of another component, such as activities and fragments. These components help you produce better-organized, and often lighter-weight code, that is easier to maintain.
onPause() lifecycle callback
The system calls this method as the first indication that the user is leaving your activity (though it does not always mean the activity is being destroyed); it indicates that the activity is no longer in the foreground (though it may still be visible if the user is in multi-window mode). Use the onPause() method to pause or adjust operations that should not continue (or should continue in moderation) while the Activity is in the Paused state, and that you expect to resume shortly.
You can also use the onPause() method to release system resources, handles to sensors (like GPS), or any resources that may affect battery life while your activity is paused and the user does not need them. However, a Paused activity may still be fully visible if in multi-window mode. As such, you should consider using onStop() instead of onPause() to fully release or adjust UI-related resources and operations to better support multi-window mode.
Completion of the onPause() method does not mean that the activity leaves the Paused state. Rather, the activity remains in this state until either the activity resumes or becomes completely invisible to the user. If the activity resumes, the system once again invokes the onResume() callback. If the activity returns from the Paused state to the Resumed state, the system keeps the Activity instance resident in memory, recalling that instance when the system invokes onResume(). In this scenario, you don’t need to re-initialize components that were created during any of the callback methods leading up to the Resumed state. If the activity becomes completely invisible, the system calls onStop()
The reasons for system to invoke onPause() callback
- Some event interrupts app execution. For instance, receiving a phone call, the user’s navigating to another activity, or the device screen’s turning off.
- In Android 7.0 (API level 24) or higher, multiple apps run in multi-window mode. Because only one of the apps (windows) has focus at any time, the system pauses all of the other apps.
- A new, semi-transparent activity (such as a dialog) opens. As long as the activity is still partially visible but not in focus, it remains paused.
Should we use onPause() to save appliaction or user data?
onPause() execution is very brief, and does not necessarily afford enough time to perform save operations. For this reason, you should not use onPause() to save application or user data, make network calls, or execute database transactions; such work may not complete before the method completes. Instead, you should perform heavy-load shutdown operations during onStop()
onStop() lifecycle callback
When your activity is no longer visible to the user, it has entered the Stopped state, and the system invokes the onStop() callback. This may occur, for example, when a newly launched activity covers the entire screen. The system may also call onStop() when the activity has finished running, and is about to be terminated.
In the onStop() method, the app should release or adjust resources that are not needed while the app is not visible to the user. For example, your app might pause animations or switch from fine-grained to coarse-grained location updates. Using onStop() instead of onPause() ensures that UI-related work continues, even when the user is viewing your activity in multi-window mode.
You should also use onStop() to perform relatively CPU-intensive shutdown operations. For example, if you can’t find a more opportune time to save information to a database, you might do so during onStop()
From the Stopped state, the activity either comes back to interact with the user, or the activity is finished running and goes away. If the activity comes back, the system invokes onRestart(). If the Activity is finished running, the system calls onDestroy()
Is the Activity object kept in memory when it’s in Stopped state?
When your activity enters the Stopped state, the Activity object is kept resident in memory: It maintains all state and member information, but is not attached to the window manager. When the activity resumes, the activity recalls this information. You don’t need to re-initialize components that were created during any of the callback methods leading up to the Resumed state. The system also keeps track of the current state for each View object in the layout, so if the user entered text into an EditText widget, that content is retained so you don’t need to save and restore it.
onDestroy() lifecycle callback
onDestroy() is called before the activity is destroyed. The system invokes this callback either because:
- the activity is finishing (due to the user completely dismissing the activity or due to finish() being called on the activity), or
- the system is temporarily destroying the activity due to a configuration change (such as device rotation or multi-window mode)
You can distinguish between these two scenarios with the isFinishing() method.
If the activity is finishing, onDestroy() is the final lifecycle callback the activity receives. If onDestroy() is called as the result of a configuration change, the system immediately creates a new activity instance and then calls onCreate() on that new instance in the new configuration.
The onDestroy() callback should release all resources that have not yet been released by earlier callbacks such as onStop().
Should you put your logic to determine why activity is being destroyed in Activity?
Instead of putting logic in your Activity to determine why it is being destroyed you should use a ViewModel object to contain the relevant view data for your Activity. If the Activity is going to be recreated due to a configuration change the ViewModel does not have to do anything since it will be preserved and given to the next Activity instance. If the Activity is not going to be recreated then the ViewModel will have the onCleared() method called where it can clean up any data it needs to before being destroyed.
What is instance state?
Instance state it is the saved data that the system uses to restore the previous state and is a collection of key-value pairs stored in a Bundle object. By default, the system uses the Bundle instance state to save information about each View object in your activity layout (such as the text value entered into an EditText widget). So, if your activity instance is destroyed and recreated, the state of the layout is restored to its previous state with no code required by you. However, your activity might have more state information that you’d like to restore, such as member variables that track the user’s progress in the activity.
Is a Bundle appropriate for preserving more than a trival amount of data?
A Bundle object isn’t appropriate for preserving more than a trivial amount of data because it requires serialization on the main thread and consumes system-process memory. To preserve more than a very small amount of data, you should take a combined approach to preserving data, using persistent local storage, the onSaveInstanceState() method, and the ViewModel class.
What is going with the activity destroyed due to system constraints (configuration change or memory pressure)?
if the system destroys the activity due to system constraints (such as a configuration change or memory pressure), then although the actual Activity instance is gone, the system remembers that it existed. If the user attempts to navigate back to the activity, the system creates a new instance of that activity using a set of saved data that describes the state of the activity when it was destroyed.
When does the system calls the onSaveInstanceState() method and what for?
As your activity begins to stop, the system calls the onSaveInstanceState() method so your activity can save state information to an instance state bundle. The default implementation of this method saves transient information about the state of the activity’s view hierarchy, such as the text in an EditText widget or the scroll position of a ListView widget.
To save additional instance state information for your activity, you must override onSaveInstanceState() and add key-value pairs to the Bundle object that is saved in the event that your activity is destroyed unexpectedly. If you override onSaveInstanceState(), you must call the superclass implementation if you want the default implementation to save the state of the view hierarchy.
To save persistent data, such as user preferences or data for a database, you should take appropriate opportunities when your activity is in the foreground. If no such opportunity arises, you should save such data during the onStop() method.