Activities and LifeCycle
Activities and LifeCycleWhat is an Activity?
An activity presents a visual user interface (screen) for one focused endeavor the user can undertake.
Example 1 - Individual activity: A list of menu items users can choose from Display of photographs along with their captions
Example 2- Sequence of activities: A text messaging application might have one activity that shows a list of contacts to send messages to, a second activity to write the message to the chosen contact, and other activities to review old messages or change settings.
Example 1 - Individual activity: A list of menu items users can choose from Display of photographs along with their captions
Example 2- Sequence of activities: A text messaging application might have one activity that shows a list of contacts to send messages to, a second activity to write the message to the chosen contact, and other activities to review old messages or change settings.
Things to Learn about Activity are 1.Declaration of Activities in manifest file 2. Activities and application 3..Activity life-cycle 4.Activity stack.
User Interaction Occurs on Views
Visual content ofthe window (screen contents) is provided by a hierarchy (tree) of views.Each view controls a particular rectangular space within the window.Parent views contain and organize the layout of their children.Leaf views (those at the bottom of the hierarchy) draw in the rectangles they control and respond to user actions directed at that space.
Views are where the activity's interaction with the user takes place.For example, a view might display a small image or button and initiate an action when the user taps that image or button.
How Visual Content is Presented?
Each activity is given a default window to draw.Typically, the window fills the screen, but it might be smaller than the screen and float ontop of other windows. A view hierarchy is placed within an activity's window by the Activity.setContentView(..) method.The content view is the View object at the root of the hierarchy.
Application is Made up with Activities :An application might consist of just one or more Activities What the activities are, and how many there are depends, of course, on the application Typically, one of the activities is marked as the first one (starting activity or main activity) that should be presented to the user when the application is launched. Specified in the AndroidManifest.xml. Moving from one activity to another is accomplished by having the current activity start (call or launch) the next one.
How an Activity Start Another?
An activity is started in two ways
startActivity(Intent intent) - Used when starting an activity (calling an activity) doesnot expect a result
startActivityForResult(Intent intent) - Used when starting activity expects a result from the started activity
The responding activity (started activity or target activity) can look at the initial intent that caused it to be launched by calling its getIntent() method
Whatis Manifest File?
Every Activity has to be declared in the Manifest file - otherwise “Activity Not Found” error condition occurs
<?xml version="1.0" encoding="utf-8"?>
<manifest . . . >
<application . . . >
<activity android:name="com.example.project.SomeActivity"
android:icon="@drawable/small_pic.png"
android:label="@string/someLabel"
. . . >
</activity>
. . .
</application>
</manifest>
An Activity has three states.
“Active” (or “Running”) state:When it is in the foreground of the screen (at the top
of the activity stack for the current task). This is the activity that is the focus for the user's
actions.
of the activity stack for the current task). This is the activity that is the focus for the user's
actions.
“Paused” state: Lost focus but is still visible to the user. Another activity lies on top of it and that activity either is transparent or doesn't cover the full screen,so some of the paused activity can show through A paused activity is completely alive (it maintains all state and member information and remains attached to the window manager), but can be killed
“Stopped” state: Completely obscured by another activity It still retains all state and member information. However, it is no longer visible to the user so itswindow is hidden and it will often be killed by the system when memory is needed elsewhere.
As an activity transitions from state to state, it is notified of the change by calls to the following protected methods:
- void onCreate(Bundle savedInstanceState)
- void onStart()
- void onRestart()
- void onResume()
- void onPause()
- void onStop()
- void onDestroy()
An activity must implement onCreate() to do the initial setup when the object is first instantiated
onCreate() : Called when the activity is first created. This is where you should do all of your normal static set up Create views, bind data to lists, and so on. This method is passed a Bundle object containing the activity's previous state, if that state was captured Always followed by onStart()
Entire lifetime
Between the first call to onCreate() through to a single final call to onDestroy().
• Visible lifetime: Between a call to onStart() until a corresponding call to onStop()
• Foreground lifetime : Between a call to onResume() until a corresponding call to onPause()
• Visible lifetime: Between a call to onStart() until a corresponding call to onStop()
• Foreground lifetime : Between a call to onResume() until a corresponding call to onPause()
Figure 1 Shows the LifeCycle of an Activity
Activities in the system are managed as an activity stack. It is typical a user will be switching activities while using a mobile device Example scenario: A user is reading emails, then phone call comes in. The user takes the call (activity switch occurs) and when the phone conversation is done, goes back to reading emails (activity switch occurs) When a new activity is started, it is placed on the top of the stack and becomes the running activity The previous activity always remains below it in the stack, and will not come to the foreground again until the new activity exits.
Saving additional dataTo save additional data about the activity state, you must override the onSaveInstanceState() callback method. The system calls this method when the user is leaving your activity and passes it the Bundle object that will be saved in the event that your activity is destroyed unexpectedly. If the system must recreate the activity instance later, it passes the same Bundle object to both the onRestoreInstanceState() and onCreate() methods.
Figure 2. As the system begins to stop your activity, it calls onSaveInstanceState() (1) so you can specify additional state data you'd like to save in case the Activity instance must be recreated. If the activity is destroyed and the same instance must be recreated, the system passes the state data defined at (1) to both the onCreate() method (2) and the onRestoreInstanceState() method (3).
When your activity is recreated after it was previously destroyed, you can recover your saved state from the Bundle that the system passes your activity. Both the onCreate() and onRestoreInstanceState() callback methods receive the same Bundle that contains the instance state information.
Because the onCreate() method is called whether the system is creating a new instance of your activity or recreating a previous one, you must check whether the state Bundle is null before you attempt to read it. If it is null, then the system is creating a new instance of the activity, instead of restoring a previous one that was destroyed.
Instead of restoring the state during onCreate() you may choose to implement onRestoreInstanceState(), which the system calls after the onStart() method. The system calls onRestoreInstanceState() only if there is a saved state to restore, so you do not need to check whether the Bundle is null:
Here is an Example that demonstrates the Activity its Lifecycle ,how an activity calls another activity ,passing a value to another activity and getting value from called activity
1.Create a project SRM_Activities as shown in screen shot
Property name | Property value |
Project name | SRM_Activities |
Package name | in.ac.srmuniv.activitylifecycle |
Activity name | MainActivity |
Layout xml name | activity_main |
2.Copy the code to the file activity_main.xml in res/layout folder
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<EditText
android:id="@+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:freezesText="true" >
<requestFocus />
</EditText>
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Go to Second" />
</LinearLayout>
3.Copy the code in MainActivity.java. Activity.
packagein.ac.srmuniv.activitylifecycle;
importandroid.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
importandroid.widget.Button;
importandroid.widget.EditText;
public class MainActivity extends Activity {
private static final String TAG = "LifeCycleMethodsActivity1---->";
private EditText text;
private String KEY_SAVE__VALUE;
// Initialization of the Activity after it is first created. Must at least
// call {@link android.app.Activity#setContentView setContentView()} to
// describe what is to be displayed in the screen.
@Override
public void onCreate(Bundle savedInstanceState) {
Log.v(TAG, "onCreate() is called");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button b = (Button) findViewById(R.id.button1);
text = (EditText) findViewById(R.id.editText1);
if (savedInstanceState != null) {
if(savedInstanceState.containsKey(KEY_SAVE__VALUE)) {
Log.v(TAG, "saveInstancestate() is called");
text.setText(savedInstanceState.getString(KEY_SAVE__VALUE));
}
}
b.setOnClickListener(newView.OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(MainActivity.this,
SRM_Activities1.class);
i.putExtra("value1", text.getText().toString());
startActivity(i);
}
});
}
// Called after onCreate(Bundle) — or after onRestart() when the activity
// had been stopped, but is now again being displayed to the user. It
// will be followed by onResume().
@Override
public void onStart() {
Log.v(TAG, "onStart() is called");
super.onStart();
}
// Called after onStop() when the current activity is being re-displayed
// to the user (the user has navigated back to it). It will be followed
// by onStart() and then onResume().
@Override
public void onRestart() {
Log.v(TAG, "onRestart() is called");
super.onRestart();
}
// Called after onRestoreInstanceState(Bundle), onRestart(), or onPause(),
// for your activity to start interacting with the user. This is a good
// place to begin animations, open exclusive-access devices (such as the
// camera), etc.
@Override
public void onResume() {
Log.v(TAG, "onResume() is called");
super.onResume();
}
// Called as part of the activity lifecycle when an activity is going
// into the background, but has not (yet) been killed. The counterpart
// to onResume().
@Override
public void onPause() {
Log.v(TAG, "onPause() is called");
super.onPause();
}
// Called when you are no longer visible to the user. You will next
// receive either onRestart(), onDestroy(), or nothing, depending on
// later user activity.
@Override
public void onStop() {
Log.v(TAG, "onStop() is called");
super.onStop();
}
// 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.
@Override
public void onDestroy() {
Log.v(TAG, "onDestroy() is called");
super.onDestroy();
}
@Override
public voidonSaveInstanceState(Bundle outState) {
outState.putString(KEY_SAVE__VALUE, text.getText().toString());
Log.v(TAG, "onSaveInstance() is called");
super.onSaveInstanceState(outState);
}
public voidonRestoreInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);
Log.v(TAG, "onRestoreInstanceState() is called");
text.setText(savedInstanceState.getString(KEY_SAVE__VALUE));
}
}
4.Copy the Androidmanifest.xml code from the one given below
<?xml version="1.0"encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="in.ac.srmuniv"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
5.Run the application in the emulator.
Figure 3 Shows MainActivity in foreground when application is started
Figure 3 Shows MainActivity in foreground when application is started
Figure 4 Shows Log Cat view when Activity is Active (Started) LifecycleMethodsActivity 1 TAG shows what are the methods called when an activity comes to foreground
Figure 5 Shows Log Cat view when Activity is Killed when user presses back button (Destroyed)
6.Create second.xml and edit the code as given below
<?xml version="1.0"encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Go To Third" >
</Button>
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Go back to First" >
</Button>
</LinearLayout>
7.Create another activity SRM_Activities1.java copy the code as given below
packagein.ac.srmuniv.activitylifecycle;
importandroid.app.Activity;
importandroid.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
importandroid.view.View.OnClickListener;
importandroid.widget.Button;
importandroid.widget.TextView;
public class SRM_Activities1 extends Activity implements OnClickListener {
private int request_Code = 1;
TextView txt;
private static final String TAG = "LifeCycleMethodsActivity2---->";
// Initialization of the Activity after it is first created. Must at least
// call {@link android.app.Activity#setContentView setContentView()} to
// describe what is to be displayed in the screen.
@Override
public void onCreate(Bundle savedInstanceState) {
Log.v(TAG, "onCreate() is called");
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
Button b = (Button) findViewById(R.id.button1);
Button b2 = (Button) findViewById(R.id.button2);
b.setOnClickListener(this);
b2.setOnClickListener(this);
Bundle bundle = getIntent().getExtras();
txt = (TextView) findViewById(R.id.textView1);
txt.setText(bundle.getString("value1"));
}
public void onClick(View v) {
if (v.getId() == R.id.button1) {
startActivityForResult(newIntent(SRM_Activities1.this,
SRM_Activities2.class), request_Code);
} else if (v.getId() == R.id.button2) {
startActivity(newIntent(SRM_Activities1.this, MainActivity.class));
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == request_Code) {
if (resultCode == RESULT_OK) {
txt.setText(data.getData().toString());
}
}
}
// Called after onCreate(Bundle) — or after onRestart() when the activity
// had been stopped, but is now again being displayed to the user. It
// will be followed by onResume().
@Override
public void onStart() {
Log.v(TAG, "onStart() is called");
super.onStart();
}
// Called after onStop() when the current activity is being re-displayed
// to the user (the user has navigated back to it). It will be followed
// by onStart() and then onResume().
@Override
public void onRestart() {
Log.v(TAG, "onRestart() is called");
super.onRestart();
}
// Called after onRestoreInstanceState(Bundle), onRestart(), or onPause(),
// for your activity to start interacting with the user. This is a good
// place to begin animations, open exclusive-access devices (such as the
// camera), etc.
@Override
public void onResume() {
Log.v(TAG, "onResume() is called");
super.onResume();
}
// Called as part of the activity lifecycle when an activity is going
// into the background, but has not (yet) been killed. The counterpart
// to onResume().
@Override
public void onPause() {
Log.v(TAG, "onPause() is called");
super.onPause();
}
// Called when you are no longer visible to the user. You will next
// receive either onRestart(), onDestroy(), or nothing, depending on
// later user activity.
@Override
public void onStop() {
Log.v(TAG, "onStop() is called");
super.onStop();
}
// 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.
@Override
public void onDestroy() {
Log.v(TAG, "onDestroy() is called");
super.onDestroy();
}
}
8.Modify the Androidmanifest.xml code from the one given below to add entry for SRM_Activities1
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="in.ac.srmuniv.activitylifecycle"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="MainActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SRM_Activities1"
android:label="SecondActivity" >
</activity>
</application>
</manifest>
10 Run the application again Watch the LogCat when One activity calls another activity by viewing the TAG "LifeCycleMethodsActivity2---->"
Figure 7 Shows the value typed in the MainActivity in EditText is passed to SRM_Activity1 when Button was clicked .The passed value through putExtra() method of Intent in MainActivity is received in OnCreate() of SRM_Activity1 Activity through bundle object calling method bundle.getString("value1")
Figure 8 Shows the Log Cat view which depicts the call of methods happening in Activities when one Activity calls other .Calling Activity stacks itself in activity stack.
11.Create third.xml in Layout folder with code given below
<?xml version="1.0"encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<EditText
android:id="@+id/editText1"
android:layout_width="166dp"
android:layout_height="wrap_content" >
<requestFocus />
</EditText>
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="gotoSecond"
android:text="Go to Second" />
</LinearLayout>
12.Create another Activity SRM_Activities2.java copy the code give below in to it.
package in.ac.srmuniv.activitylifecycle;
importandroid.app.Activity;
importandroid.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
importandroid.widget.Button;
importandroid.widget.EditText;;
public class SRM_Activities2 extends Activity {
EditText txt;
private static final String TAG = "LifeCycleMethodsActivity3---->";
@Override
public void onCreate(Bundle savedInstanceState) {
Log.v(TAG, "onCreate() is called");
super.onCreate(savedInstanceState);
setContentView(R.layout.third);
Button b=(Button)findViewById(R.id.button1);
txt=(EditText)findViewById(R.id.editText1);
}
public void gotoSecond(View v)
{
Intent data = new Intent();
data.setData(Uri.parse(txt.getText().toString()));
setResult(RESULT_OK, data);
finish();
}
@Override
public void onStart() {
Log.v(TAG, "onStart() is called");
super.onStart();
}
@Override
public void onRestart() {
Log.v(TAG, "onRestart() is called");
super.onRestart();
}
@Override
public void onResume() {
Log.v(TAG, "onResume() is called");
super.onResume();
}
@Override
public void onPause() {
Log.v(TAG, "onPause() is called");
super.onPause();
}
@Override
public void onStop() {
Log.v(TAG, "onStop() is called");
super.onStop();
}
@Override
public void onDestroy() {
Log.v(TAG, "onDestroy() is called");
super.onDestroy();
}
}
13.Modify the Androidmanifest.xml file with the code give below
<?xml version="1.0"encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="in.ac.srmuniv"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="in.ac.srmuniv.MainActivity"
android:label="MainActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name=".SRM_Activities1"
android:label="SecondActivity" >
</activity>
<activity
android:name=".SRM_Activities2"
android:label="ThirdActivity" >
</activity>
</application>
</manifest>
6Fi SRM_Activities1 Activity registers on onClickListener for two buttons "Go to Third" and "Go to First" calling of SRM_Activities2 through startActivityForResult() expects result values to be returned from called Activity (SRM_Activities1).onActivityResult() will be called when SRM_Activities2 finishes and returns result
Figure 10 Shows the SRM_Activities1 Figure 11 Shows SRM_Activities2 returning result back value to the called Activity SRM_Activities1.
Figure 12 Shows LogCat view when SRM_Activity2 is destroyed and SRM_Activity1 is restarted.
CODE EXPLANATION
The example explains life cycle of Activity one can see the the sequence of method call when it is created and it comes to active state,onCreate ,onStart.onResume are sequence of method call.when it goes in to background,onPause method is called the Activity is visible(partially too) but inactive then onStop method Activity is completely invisible onSaveInstance is called before onStop where we store activity the data of the activity in key/values pair which could be retrieved when activity is unexpectedly destroyed and the same instance of Activity is recreated later.The Activity state can be recovered in onCreate() method or through onRestoreInstanceState() method,but onRestoreInstanceState() method will be called only if previously destroyed Activity instance has to be recreated.
The following code snippets show the call back method for onClick event of Button is entered as an attribute in Button item in XML layout file.data is passed to called Activity through setdata method of Intent and finish() method kills the Activity itself.
public void gotoSecond(View v) {
Intent data = new Intent();
data.setData(Uri.parse(txt.getText().toString()));
setResult(RESULT_OK, data);
finish();
}
goTosecond() is a registered onClick() method done through layout xml file for the Thrid acivity <Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="gotoSecond"
android:text="Go to Second" />