Thursday, February 9, 2012

Explain Activity LifeCycle of Android?

Writing an application with a good understanding of the activity life cycle is critical to ensure that our application provides a seamless user experience and properly manages its resources.
Android application does not control its own process lifetimes. The Android run time manages the process of each application. While the run time handles the termination and management of an activity's process, the activity's state helps determine the priority of its parent application. The application priority, in turn, affects the likelihood that the run time will terminate it and the activities running within it.


Activity Stacks
The state of each activity is determined by its position on the activity stack. When a new activity starts, the current foreground screen is moved to the top of the stack. If the user navigates back using the Back button or the foreground activity is closed, the next activity on the stack moves up and becomes active.
An application's priority is influenced by its highest-priority activity. When the Android memory manager is deciding which application to terminate to free resources, it uses this stack to determine the priority of applications based on their activities.


Activity States
As activities are created and destroyed they move in and out of the stack. They transition through 4 states:
  • Active
    When an activity is at the top of the stack it is the visible, focused, foreground activity that is receiving user input. Android will attempt to keep it alive at all cost, killing activities further down the stack as needed, to ensure that it has the resources it needs. When another activity becomes active, this one will be paused.
  • Paused
    In some cases our activity will be visible but will not have focus. At this point it's paused. This state is reached if a transparent or not-full-screen activity is active in front of it. When paused, an activity is treated as if it were active. However, it doesn't receive user input events. In extreme cases, Android will kill a paused activity to recover resources for the active activity. When an activity becomes totally obscured, it is stopped.
  • Stopped
    When an activity isn't visible, it stops. The activity will remain in memory, retaining all state information. However, it is now a candidate for termination when the system requires memory elsewhere. When an activity stopped, it's important to save data and the current UI state. Once an activity exited or closed, it becomes inactive.
  • Inactive
    After an activity has been killed, and before it's been launched, it's inactive. Inactive activities have been removed from the activity stack and need to be restarted before they can be displayed and used.
State transitions are nondeterministic and are handled entirely by the Android memory manager. Android will start by closing applications that contain inactive activities, followed by those that are stopped. In extreme cases it will remove those that are paused.

Activity Lifetimes
Within an activity's full lifetime, between creation and destruction, it will go through one or more iterations of the active and visible lifetimes. Each transition will trigger the method handlers as shown in the previous code sample.


Full Lifetime
The full life time of our activity occurs between the first call to onCreate() and the final call to onDestroy(). It's possible, in some cases, for an activity's process terminates without the onDestroy() not being called.
Use the onCreate() method to initialize activity. Inflate the user interface, allocate references to class variables, bind data to controls, and create services and threads. The onCreate() method is passed a Bundle to restore the user interface to its previous state, either within the onCreate() method or by overriding onRestoreInstanceState().
It's recommended that we avoid the creation of short-term objects. Rapid creation and destruction of objects force additional garbage collection.


Visible Lifetime
An activity's visible lifetimes are bound between calls to onStart() and onStop(). Between these calls our activity will be visible to the user, although it may not have focus and may be partially obscured. Activities are likely to go through several visible lifetimes during their full lifetime, as they move between the foreground and background. While it's unusual, Android run time will kill an activity during its visible lifetime without a call to onStop().
The onStop() method should be used to pause or stop animations, threads, sensor listeners, GPS lookups, timers, services, or other processes that are used exclusively to update the user interface. There's little value in consuming resources to update the UI when it isn't visible. Use the onStart() method to resume or restart these processes when the UI is visible again.
The onStart() method is called immediately prior to all but the first call to onStart(). Use it to implement special processing that we want done only when the activity restarts within its full lifetime.
The onStart()/onStop() methods are also used to register and unregister Broadcast Receivers that are being used exclusively to update the user interface.


Active Lifetime
The active lifetime starts with a call to onResume() and ends with a call to onPause().
An active activity is in the foreground and its receiving user input events. Our activity is likely to go through several active lifetimes before it's destroyed, as the active lifetime will end when a new activity is displayed, the device goes to sleep, or the activity loses focus. Try to keep code in the onPause() and onResume() methods relatively fast and lightweight to ensure that our application remains responsive when moving in and out of the foreground.
Immediately before onPause(), a call is made to onSaveInstanceState(). This method provides an opportunity to save the activity's UI state in a Bundle that will be passed to the onCreate() and onRestoreInstanceState() methods. UseonSaveInstanceState() to save the UI state to ensure that the activity can present the same UI when it next becomes active. We can safely assume that during the active lifetime onSaveInstanceState() and onPause() will be called before the process is terminated.
Most activity implementations will override at least the onPause() method to commit unsaved changes, as it marks the point beyond which an activity may be killed without warning. Depending on our application, we may also choose to suspend threads, processes, Broadcast Receivers while our activity is not in the foreground.
The onResume() method can be very lightweight. We will not need to reload the UI state here as this is handled by theonCreate() and onRestoreInstanceState() methods when required. Use onResume() to reregister any Broadcast Receivers or other processes we may have suspended in onPause().
In Details for Each Methods........

OnCreate

This method is called when the activity is first created. An activity should override this method to setup its main content view and perform any other initial setup, such as creating views, binding data to lists, etc. This method also provides an activity with a Bundle parameter, which is a dictionary for storing and passing state information and objects between activities. If the bundle is non-null, this indicates the activity is resuming and can be rehydrated. Activities can also make use of the Extras container of the Intent object to restore data previously saved, or data that is being passed between activities. For example, the following code illustrates how to retrieve values from the bundle, and also how to retrieve values from the Extras container:

OnStart

This method is called when the activity is about to become visible to the user. Activities should override this method if they need to perform any specific tasks right before an activity becomes visible, such as: refreshing current values of views within the activity, or ramping up frame rates (a common task in game building).

OnPause

This method is called when the system is about to put the activity into the background. Activities must override this method if they need to commit unsaved changes to persistent data, destroy or cleanup other objects consuming resources, or ramp down frame rates, etc. Implementations of this method should return as quickly as possible, as no successive activity will be resumed until this method returns. The following example illustrates how to override the OnPause method to save data in the Extras container, to enable the data to be passed between activities:

OnResume

This method is called when the activity will start interacting with the user after being in a pause state. When this method is called, the activity is moving to the top of the activity stack, and it is receiving user input. Activities can override this method if they need to perform any tasks after the activity begins accepting user input.

OnStop

This method is called when the activity is no longer visible to the user, because another activity has been resumed or started and is covering this one. This can happen because the activity is completing (Finish method was called) because the system is destroying this instance of the activity to save resources, or because an orientation change has occurred for the device. You can distinguish between these two scenarios by using the IsFinishing property. An activity should override this method if it needs to perform any specific tasks before it is destroyed, or if it’s about to initiate a UI rebuild after an orientation change.

OnRestart

This method is called after your activity has been stopped, prior to it being started again. This method is always followed by OnStart. An activity should override OnRestart if it needs to perform any tasks immediately before OnStart is called. For instance, if the activity has previously been sent to the background and OnStop has been called, but the activity’s process has not yet been destroyed by the OS, then the OnRestart method should be overridden.
A good example of this would be when the user presses the home button while on an activity in the application. The OnPause, and then the OnStop methods are called, but the activity is not destroyed. If the user were then to restore the application by using the task manager or a similar application, the OnRestart method of the activity would be called by the OS, during the activities reactivation.

OnDestroy

This is the final method that is called on an activity before it’s destroyed. After this method is called, your activity will be killed and purged from the resource pools of the device. The OS will permanently destroy the state data of an activity after this method runs, so an activity should override this method as a final means to save state data.

OnSaveInstanceState

This method is provided by the Android activity lifecycle framework to give an activity the opportunity to save its data when a change occurs, for example, a screen orientation change. The following code illustrates how activities can override the OnSaveInstanceState method to save data for rehydration when the OnCreate method is called:


 onRestoreInstanceState

 This is called when the activity is being reinitialized from a state previously saved by the onSaveInstanceState() method.The default implementation restores the state of your user interface

Example suppose we have two activity Activity1 and Activity2...

Activity1


package com.example.androidexample;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Log.e("----------On Create", "On Create");
Button btn1 = (Button) findViewById(R.id.btn1);
btn1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
Intent mainIntent = new Intent(MainActivity.this,Activity2.class);
startActivity(mainIntent);
//finish();
}
});
}

@Override
protected void onRestart() {
//Toast.makeText(MainActivity.this, "On Restart", Toast.LENGTH_SHORT).show();
Log.e("----------On Restart", "On Restart");
super.onRestart();
}

@Override
protected void onStart() {
//Toast.makeText(MainActivity.this, "On Start", Toast.LENGTH_SHORT).show();
Log.e("----------On Start", "On Start");
super.onStart();
}

@Override
protected void onResume() {
//Toast.makeText(MainActivity.this, "On Resume", Toast.LENGTH_SHORT).show();
Log.e("----------On Resume", "On Resume");
super.onResume();
}

@Override
protected void onPause() {
//Toast.makeText(MainActivity.this, "On Pause", Toast.LENGTH_SHORT).show();
Log.e("----------On Pause", "On Pause");
super.onPause();
}

@Override
protected void onStop() {
//Toast.makeText(MainActivity.this, "On Stop", Toast.LENGTH_SHORT).show();
Log.e("----------On Stop", "On Stop");
super.onStop();
}

@Override
protected void onDestroy() {
//Toast.makeText(MainActivity.this, "On Destroy", Toast.LENGTH_SHORT).show();
Log.e("----------On Destroy", "On Destroy");
super.onDestroy();
}

@Override
protected void onSaveInstanceState(Bundle outState) {
//Toast.makeText(MainActivity.this, "On Save Instance", Toast.LENGTH_SHORT).show();
Log.e("----------On Save Instance", "On Save Instance");
outState.putString("a", "a");
super.onSaveInstanceState(outState);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
//Toast.makeText(MainActivity.this, "On Restore Instance", Toast.LENGTH_SHORT).show();
Log.e("----------On Restore Instance", "On Restore Instance");
super.onRestoreInstanceState(savedInstanceState);
}

@Override
public Object onRetainNonConfigurationInstance() {
Log.e("----------On Retain Non Configuartion Instance", "On Retain Non Configuartion Instance");
return super.onRetainNonConfigurationInstance();
}

@Override
public Object getLastNonConfigurationInstance() {
Log.e("----------On get Last Non Configuration Instance", "On get Last Non Configuration Instance");
return super.getLastNonConfigurationInstance();
}

}

Activity2


package com.example.androidexample;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class Activity2 extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.acitivity2);

Button btn1 = (Button) findViewById(R.id.btn2);
btn1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
Intent mainIntent = new Intent(Activity2.this,
MainActivity.class);
startActivity(mainIntent);
//finish();

}
});
}

}

Below is the output if the following condition occurs....


Normal Launch Of Activity 1


09-10 14:46:24.806: E/----------On Create(5517): On Create
09-10 14:46:24.806: E/----------On Start(5517): On Start
09-10 14:46:24.807: E/----------On Resume(5517): On Resume


On Rotation of Activity 1

09-10 14:45:11.109: E/----------On Save Instance(5517): On Save Instance
09-10 14:45:11.110: E/----------On Pause(5517): On Pause
09-10 14:45:11.110: E/----------On Stop(5517): On Stop
09-10 14:45:11.110: E/----------On Retain Non Configuartion Instance(5517): On Retain Non Configuartion Instance
09-10 14:45:11.110: E/----------On Destroy(5517): On Destroy
09-10 14:45:11.230: E/----------On Create(5517): On Create
09-10 14:45:11.230: E/----------On Start(5517): On Start
09-10 14:45:11.230: E/----------On Restore Instance(5517): On Restore Instance
09-10 14:45:11.231: E/----------On Resume(5517): On Resume


While Navigating to Activity 2

09-10 14:47:24.041: E/----------On Save Instance(5517): On Save Instance
09-10 14:47:24.041: E/----------On Pause(5517): On Pause
09-10 14:47:24.286: E/----------On Stop(5517): On Stop

But if we Finish Activity before navigating to Activity 2 then below methods will also be called i.e. onDestroy()


09-10 14:47:24.041: E/----------On Pause(5517): On Pause
09-10 14:47:24.286: E/----------On Stop(5517): On Stop
09-10 14:49:33.723: E/----------On Destroy(5651): On Destroy

If we press back from Activity 1 then.
09-10 14:53:56.769: E/----------On Pause(5651): On Pause
09-10 14:53:57.028: E/----------On Stop(5651): On Stop
09-10 14:53:57.028: E/----------On Destroy(5651): On Destroy


If we press Home then.
09-10 14:55:13.681: E/----------On Save Instance(5651): On Save Instance
09-10 14:55:13.681: E/----------On Pause(5651): On Pause
09-10 14:55:13.942: E/----------On Stop(5651): On Stop


Again Starting the app.
09-10 14:55:59.912: E/----------On Restart(5651): On Restart
09-10 14:55:59.912: E/----------On Start(5651): On Start
09-10 14:55:59.912: E/----------On Resume(5651): On Resume





1 comment:

  1. You can get a nice and easy tutorial with example at http://androidtechpoint.blogspot.com/2017/08/android-activity-life-cycle-tutorial-with-example.html

    ReplyDelete