Android Activity State Changes - An Android Studio Example

From Techotopia
Revision as of 19:59, 27 October 2016 by Neil (Talk | contribs) (Text replacement - "<table border="0" cellspacing="0">" to "<table border="0" cellspacing="0" width="100%">")

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
PreviousTable of ContentsNext
Handling Android Activity State Changes in Android StudioSaving and Restoring Activity State in Android Studio


You are currently reading the Android Studio 1.x - Android 5 Edition of this book.

Purchase the fully updated Android Studio Hedgehog Edition of this publication in eBook ($32.99) or Print ($49.99) format

Android Studio Hedgehog Essentials - Java Edition Print and eBook (PDF) editions contain 87 chapters and over 800 pages
Buy Print Preview Book


The previous chapters have discussed in some detail the different states and lifecycles of the activities that comprise an Android application. In this chapter, we will put the theory of handling activity state changes into practice through the creation of an example application. The purpose of this example application is to provide a real world demonstration of an activity as it passes through a variety of different states within the Android runtime.

In the next chapter, entitled Saving and Restoring Activity State in Android Studio, the example project constructed in this chapter will be extended to demonstrate the saving and restoration of dynamic activity state.


Contents


Creating the State Change Example Project

The first step in this exercise is to create the new project. Begin by launching Android Studio and, if necessary, closing any currently open projects using the File -> Close Project menu option so that the Welcome screen appears.

Select the Start a new Android Studio project quick start option from the welcome screen and, within the resulting new project dialog, enter StateChange into the Application name field and ebookfrenzy.com as the Company Domain setting before clicking on the Next button.

On the form factors screen, enable the Phone and Tablet option and set the minimum SDK setting to API 8: Android 2.2 (Froyo). Continue to proceed through the screens, requesting the creation of a blank activity named StateChangeActivity a corresponding layout named activity_state_change and a menu resource named menu_state_change.

Upon completion of the project creation process, the StateChange project should be listed in the Project tool window located along the left-hand edge of the Android Studio main window with the activity_state_change.xml layout file pre-loaded into the Designer as illustrated in Figure 12-1:


The layout file for an Android Activity loaded into Android Studio

Figure 12-1


The next action to take involves the design of the user interface for the activity. This is stored in a file named activity_state_change.xml which should already be loaded into the Designer tool. If it is not, one way to access this file is to navigate to it in the project tool window where it can be found in the app -> res -> layout folder. Once located, double clicking on the file will load it into the Android Studio Designer tool. A quicker option, however, is to use the Go to declaration editor shortcut, the purpose of which is to take you directly to the file and location where the currently selected item in the editor window is declared.

In this case, the activity_state_change layout is referenced in the onCreate() method of the StateChangeActivity.java file (located in the project panel under app -> java -> com.ebookfrenzy.statechange):

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_state_change);
}

To open the file in the Designer, click on the activity_state_change reference so that it highlights and press the Ctrl-B keyboard shortcut sequence. Android Studio will then open the activity_state_change.xml file in the Designer tool ready for the layout work to begin.

Designing the User Interface

With the user interface layout loaded into the Designer tool, it is now time to design the user interface for the example application. Instead of the “Hello world!” TextView currently present in the user interface design, the activity actually requires an EditText view. Select the TextView object in the Designer canvas and press the Delete key on the keyboard to remove it from the design.

From the Palette located on the left side of the Designer, locate the Text Fields category and click and drag a Plain Text component over to the visual representation of the device screen. Move the component to the center of the display so that the center guidelines appear and drop it into place so that the layout resembles that of Figure 12-2.

A simple Android Studio Designer layout

Figure 12-2


Note that the light bulb icon has appeared next to the view indicating that assistance is available to us in configuring this component. When working with EditText views in an Android user interface it is necessary to declare the input type for the view. This simply defines the type of text or data that will be entered by the user. For example, if the input type is set to Phone, the user will be restricted to entering numerical digits into the view. Alternatively, if the input type is set to TextCapCharacters, the input will default to upper case characters. Input type settings may also be combined.

For the purposes of this example, we will set the input type to support general text input. To do so, click on the light bulb icon followed by the right facing arrow at the end of the message describing the problem. From the list of potential solutions (Figure 12-3) click on the Add inputType attribute option:


Fixing the input type value on an EditText view in Android Studio

Figure 12-3


From the resulting Set Attribute Value dialog, select the text option from the drop down menu.

The final step in the user interface design process is to increase the width of the TextView component. With the component selected in the layout, scroll down the list of attributes in the Properties panel until the width attribute comes into view and enter a value of 200dp as outlined in Figure 12-4:


Setting a width property in the Android Studio Designer tool

Figure 12-4

You are currently reading the Android Studio 1.x - Android 5 Edition of this book.

Purchase the fully updated Android Studio Hedgehog Edition of this publication in eBook ($32.99) or Print ($49.99) format

Android Studio Hedgehog Essentials - Java Edition Print and eBook (PDF) editions contain 87 chapters and over 800 pages
Buy Print Preview Book


Overriding the Activity Lifecycle Methods

At this point, the project contains a single activity named StateChangeActivity, which is derived from the Android ActionBarActivity class. The source code for this activity is contained within the StateChangeActivity.java file which should already be open in an editor session and represented by a tab in the editor tab bar. In the event that the file is no longer open, navigate to it in the Project tool window panel (app -> java -> com.ebookfrenzy.statechange -> StateChangeActivity) and double click on it to load the file into the editor. Once loaded the code should read as follows:

package com.ebookfrenzy.statechange;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;


public class StateChangeActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_state_change);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_state_change, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

}

So far the only lifecycle method overridden by the activity is the onCreate() method which has been implemented to call the super class instance of the method before setting up the user interface for the activity. We will now modify this method so that it outputs a diagnostic message in the Android Studio LogCat panel each time it executes. For this, we will use the Log class, which requires that we import android.util.Log and declare a tag that will enable us to filter these messages in the log output:

package com.ebookfrenzy.statechange;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.util.Log;

public class StateChangeActivity extends ActionBarActivity {

    private static final String TAG = "com.ebookfrenzy.StateChange";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_state_change);
        Log.i(TAG, "onCreate");
    }

.
.
.
}

The next task is to override some more methods, with each one containing a corresponding log call. These override methods may be added manually or generated using the Alt-Insert keyboard shortcut as outlined in the chapter entitled The Basics of the Android Studio Code Editor. Note that the Log calls will still need to be added manually if the methods are being auto-generated:

    @Override
    protected void onStart() {
        super.onStart();
        Log.i(TAG, "onStart");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.i(TAG, "onResume");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.i(TAG, "onPause");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.i(TAG, "onStop");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.i(TAG, "onRestart");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestroy");
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
	 super.onSaveInstanceState(outState);
        Log.i(TAG, "onSaveInstanceState");
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
	 super.onRestoreInstanceState(savedInstanceState);
        Log.i(TAG, "onRestoreInstanceState");
    }

Filtering the LogCat Panel

The purpose of the code added to the overridden methods in StateChangeActivity.java is to output logging information to the LogCat panel within the Android tool window. With no filters defined, the log will list every event that takes place within the device or emulator making it difficult to find the log messages for our overridden methods. Before running the application, therefore, it is recommended to create a filter which, when selected, will ensure that only those log messages containing the tag declared in our activity are displayed.

Begin by displaying the Android tool window using either the tools menu button located in the far left corner of the status bar or the Alt-6 keyboard shortcut. Within the tool window, make sure that the Devices|logcat tab is selected before accessing the menu in the upper right hand corner of the panel (which will probably currently read No Filters). From this menu, select the Edit Filter Configuration menu option as shown in Figure 12-5:


Creating a new Android Studio LogCat Filter

Figure 12-5


In the Create New Logcat Filter dialog (Figure 12-6), name the filter Lifecycle and, in the by Log Tag (regex) field, enter the Tag value declared in StateChangeActivity.java (in the above code example this was com.ebookfrenzy.StateChange but you may have changed this to reflect your company’s URL).


Configuring a LogCat filter in Android Studio

Figure 12-6


When the changes are complete, click on the OK button to create the filter and dismiss the dialog. Instead of listing No Filters, the newly created filter should now be selected in the Android tool window.

Running the Application

For optimal results, the application should be run on a physical Android device, details of which can be found in the chapter entitled Testing Android Applications on a Physical Android Device with ADB. With the device configured and connected to the development computer, click on the run button represented by a green triangle located in the Android Studio toolbar as shown in Figure 12-7 below, select the Run -> Run… menu option or use the Shift+F10 keyboard shortcut:


The Android Studio run toolbar button

Figure 12-7


Select the physical Android device from the Choose Device dialog if it appears (assuming that you have not already configured it to be the default target). After Android Studio has built the application and installed on the device it should start up and be running in the foreground.

A review of the LogCat panel should indicate which methods have so far been triggered (taking care to ensure that the Lifecycle filter created in the preceding section is selected to filter out log events that are not currently of interest to us):


The Android Studio LogCat and DDMS tool window

Figure 12-8


Experimenting with the Activity

With the diagnostics working, it is now time to exercise the application with a view to gaining an understanding of the activity lifecycle state changes. To begin with, consider the initial sequence of log events in the LogCat panel:

onCreate
onStart
onResume

Clearly, the initial state changes are exactly as outlined in Figure 9 2. Note, however, that a call was not made to onRestoreInstanceState() since the Android runtime detected that there was no state to restore in this situation.

Tap on the Home icon in the bottom status bar on the device display and note the sequence of method calls reported in the log as follows:

onPause
onSaveInstanceState
onStop

In this case, the runtime has noticed that the activity is no longer in the foreground, is not visible to the user and has stopped the activity, but not without providing an opportunity for the activity to save the dynamic state. Depending on whether the runtime ultimately destroyed the activity or simply restarted it, the activity will either be notified it has been restarted via a call to onRestart() or will go through the creation sequence again when the user returns to the activity.

As outlined in Understanding Android Application and Activity Lifecycles, the destruction and recreation of an activity can be triggered by making a configuration change to the device, such as rotating from portrait to landscape. To see this in action, simply rotate the device while the StateChange application is in the foreground. When using the emulator, device rotation may be simulated using the Ctrl-F12 keyboard shortcut or by pressing the number 7 on the keyboard keypad while Num Lock is off. The resulting sequence of method calls in the log should read as follows:

onPause
onSaveInstanceState
onStop
onDestroy
onCreate
onStart
onRestoreInstanceState
onResume

Clearly, the runtime system has given the activity an opportunity to save state before being destroyed and restarted.

Summary

The old adage that a picture is worth a thousand words holds just as true for examples when learning a new programming paradigm. In this chapter, we have created an example Android application for the purpose of demonstrating the different lifecycle states through which an activity is likely to pass. In the course of developing the project in this chapter, we also looked at a mechanism for generating diagnostic logging information from within an activity.

In the next chapter, we will extend the StateChange example project to demonstrate how to save and restore an activity’s dynamic state.


You are currently reading the Android Studio 1.x - Android 5 Edition of this book.

Purchase the fully updated Android Studio Hedgehog Edition of this publication in eBook ($32.99) or Print ($49.99) format

Android Studio Hedgehog Essentials - Java Edition Print and eBook (PDF) editions contain 87 chapters and over 800 pages
Buy Print Preview Book



PreviousTable of ContentsNext
Handling Android Activity State Changes in Android StudioSaving and Restoring Activity State in Android Studio