Application Structure

Download as pdf or txt
Download as pdf or txt
You are on page 1of 15

Unit 2

Application Structure
Introducing the Android Manifest
What is an Android Manifest?
Structure of the Manifest File
Elements of the manifest
Resources & R.java
Assets
Layouts and Drawable Resources
Activity and Activity Lifecycle
Create an activity
Adding it to the manifest
The Activity Life Cycle
Understanding the Lifecycle Methods
Saving Activity State
Restoring State of Activity
Support Multiple Screen Sizes
Gradle
Unit 2

Application Structure
A project is an organizational unit that represents a complete software solution. A project in Android
Studio is like a workspace in other Android development tools. In Android Studio, a project can
contain multiple modules. A module is like a folder which contains files. Application structure of a
sample project in Android Studio, is as follows:

Introducing the Android Manifest

What is an Android Manifest?


Every Android project includes a special file called the Android manifest file. The Android system
uses this file to determine application configuration settings, including the application’s identity as
well as what permissions the application requires to run. We will examine the Android manifest file
in detail and look at how different applications use its features.

The manifest is made up of a root manifest tag with a package attribute set to the project’s package.
It usually includes an xmlns:android attribute that supplies several system attributes used within the
file. XML snippet of a typical manifest node is as follows:
Unit 2

<manifest xmlns:android=http://schemas.android.com/apk/res/android

package=”com.example.myapp”>

[... manifest nodes ... ]

</manifest>

Structure of the Manifest File


XML snippet of a typical manifest file structure is as follows:

<?xml version="1.0" encoding="utf-8"?>

<manifest>

<uses-permission />
<permission />
<permission-tree />
<permission-group />
<instrumentation />
<uses-sdk />
<uses-configuration />
<uses-feature />
<supports-screens />
<compatible-screens />
<supports-gl-texture />

<application>

<activity>
<intent-filter>
<action />
<category />
<data />
</intent-filter>
<meta-data />
</activity>

<activity-alias>
<intent-filter> . . . </intent-filter>
<meta-data />
</activity-alias>
Unit 2

<service>
<intent-filter> . . . </intent-filter>
<meta-data/>
</service>

<receiver>
<intent-filter> . . . </intent-filter>
<meta-data />
</receiver>

<provider>
<grant-uri-permission />
<meta-data />
<path-permission />
</provider>

<uses-library />

</application>

</manifest>

Elements of the manifest


Application: A manifest can contain only one application node. It uses attributes to specify the
metadata for your application including its title, icon, and theme. It also acts as a container for other
components. Here is the syntax for defining application in manifest:

<application android:icon=”@drawable/icon” android:theme=”@style/news”>

[... application nodes ...]

</application>

Activity: An activity tag is needed for every Activity displayed by your application. The class name
can be specified using the android:name attribute. Trying to start an Activity that’s not defined in the
manifest will throw a runtime exception. Here is the syntax for defining activities in manifest:

<activity android: name=”.MainActivity” android:label=”@string/NewsReader”>

<intent-filter>

<action android: name=”android.intent.action.MAIN” />

<category android: name=”android.intent.category.LAUNCHER” />

</intent-filter>

</activity>
Unit 2

Service: There should be a service tag for each Service class used in your application. Service tags
support intent-filter child tags to allow late runtime binding. Following is the XML syntax for service:

<service android: enabled=”true” android: name=”.NewsService”></service>

Provider: Content Providers are used to manage database access and sharing within and between
applications. Following is the XML syntax for provider:

<provider android: permission=”com.yourname.Your_PERMISSION”

android: name=”.NewsProvider”

android: enabled=”true”

android: authorities=”com.yourname.newsreader.NewsProvider”>

</provider>

Receiver: By adding a receiver tag, you can register a Broadcast Receiver without having to launch
your application first. By registering a Broadcast Receiver in the manifest, you can make this
process entirely autonomous. If a matching Intent is broadcast, your application will be started
automatically and the registered Broadcast Receiver (java file) will be run. Following is the XML
syntax for receiver:

<receiver android: enabled=”true”

android: label=”Content Receiver”

android: name=”.ContentReceiver”>

</receiver>

Uses-permission: Uses-permission tags declare the permissions you’ve determined that your
application needs for it to operate properly. The permissions you include will be presented to the
user, to grant or deny, during installation. Following is the XML syntax for uses-permission:

<uses-permission android: name=”android.permission.ACCESS_LOCATION”>

</uses-permission>

Permission: Permission tags are used to restrict the access to an application component.
Application components can then add them by using the android: permission attribute. Within the
permission tag, you can specify the level of access the permission will permit, a label, and an
external resource containing the description that explain the risks of granting this permission.

Following is the XML syntax for permission:

<permission android:name=”com.yourname.DETONATE_DEVICE”

android: protectionLevel=”dangerous”

android: label=”Self Destruct”


Unit 2

android: description=”@string/detonate_description”>

</permission>

Instrumentation: Instrumentation classes provide a framework for running tests on your Activities
and Services at run time. They provide hooks to monitor your application and its interaction with the
system resources. Following is the XML syntax for instrumentation:

<instrumentation android: label=” Testing”

android: name=”.TestClass”

android: targetPackage=”com.yourname.newsreader”>

</instrumentation>

Resources & R.java


A resource in Android application could be a variable, UI control or a file. Once you provide a
resource in your application, you can apply it by referencing its resource ID. All resource IDs are
defined in your project's R class, which the aapt tool automatically generates. aapt stands
for Android Asset Packaging Tool. This tool is part of the SDK (and build system) and allows you to
view, create, and update Zip-compatible archives (zip, jar, apk). It can also compile resources into
binary assets.

When your application is compiled, aapt generates the R class, which contains resource IDs for all
the resources in your res/ directory. For each type of resource, there is an R subclass (for
example, R.drawable for all drawable resources), and for each resource of that type, there is a static
integer (for example, R.drawable.icon). This integer is the resource ID that you can use to retrieve
your resource.

Assets
The assets is a folder that is used to store video files or custom font families which you want use in
your app. By default, assets folder won’t be present in the project. It is based on your project
requirement to create the folder. The assets folder should be created under:

src/main/assets/

Layouts and Drawable Resources


Layout resource is the folder where XML files that defines the User Interface are stored.

Drawable resource contains the bitmap file to be used in the program. There are three different
folders to store drawables. They are drawable-ldpi, drawable-mdpi and drawable-hdpi. Ldpi, mdpi
and hdpi stands for low density, medium density and high density screens respectively. The
resources for each screen resolutions are stored in respective folders and the Android system will
choose it according to the pixel density of the device.
Unit 2

Activity and Activity Lifecycle


An Activity is an application component that provides a screen with which user can interact in order
to do something. Each Activity is given a window in which it draw its user interface. Let us see Activities
in detail here:

Create an activity
To create a new activity using Android Studio:

1. Choose File->New Project. The Create New Project window will appear as follows:

2. Enter Application name, Company Domain (package name) and project location and click on
Next. It is also possible to change these values afterwards.

3. Select the minimun SDK (API levels) from which your app should work and click on Next.

4. Choose Blank Activity and click Next.

5. Enter the Activity and Layout file names (You can give any name) requested and click
Finish.

The created class will have a onCreate(), onCreateOptionsMenu() and onOptionsItemSelected()


methods overridden by default.

Following is the syntax for the Activity file class:


Unit 2

public class MainActivity extends Activity {

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

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
}

All subclasses of Activity must implement the onCreate() method. The system calls onCreate()
method when creating a new instance of the activity. You must define the activity layout with the
setContentView() method in the onCreate() method. You should also perform initial setup for the
activity components in this method.

Adding it to the manifest


All activities must be declared in your manifest file, using an activity element. When an activity is
created, by default the activity will be declared in the manifest file. If not declared, then you will have
to add the activities in the manifest yourself. It should look like this:

<application ... >


...
<activity
android:name="com.yourname.newsreader.DisplayMessageActivity"
android:label="@string/title_activity_display_message" >

</activity>
</application>
Unit 2

The Activity Life Cycle


When your activity starts for the first time, the Android system calls a set of lifecycle methods on the
activity while it comes to the foreground and gets user focus. When the user starts another activity,
the current activity moves to the background by using another set of lifecycle methods.

Understanding the Lifecycle Methods


The system calls a set of lifecycle methods in a sequence.

The above image shows various functions like 'onCreate()', 'onStart()' which gets called at various
points of an Activity Lifecycle. Let's understand each of the methods/functions in detail.

onCreate()

onCreate function is called when your Activity is getting created for the first time. It is called only
once during the entire Activity Lifecycle.

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

onStart()

onStart function gets called just before the Activity becomes visible to the user. Refer to the activity
lifecycle image shown. Notice that onStart function is called from two places - after onRestart and
OnCreate. onStart is always followed by OnResume or OnStop.
Unit 2

For example, here's an implementation of onRestart() :

@Override
protected void onStart() {
super.onStart(); // Always call the superclass method first

// The activity is either being restarted or started for the first time
// so this is where we should make sure that GPS is enabled
LocationManager locationManager =
(LocationManager) getSystemService(Context.LOCATION_SERVICE);
boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

if (!gpsEnabled) {
// Create a dialog here that requests the user to enable GPS, and use an intent
// with the android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS action
// to take the user to the Settings screen to enable GPS when they click "OK"
}
}

onResume()

onResume function gets called when your Activity comes into the foreground, and it becomes visible
to the user. At this point, the Activity is on top of the Activity stack, and the user can start interacting
with the Activity.

The following is an example for onResume() method.

@Override
public void onResume() {
super.onResume(); // Always call the superclass method first

// Get the Camera instance as the activity achieves full user focus
if (mCamera == null) {
initializeCamera(); // Local method to handle camera init
}
}

onPause()

onPause function is called when another Android activity comes on top of your Activity. Typically
anything that steals your user away from your Activity will result in onPause. It is always guaranteed
that whenever your Activity is becoming invisible or partially invisible, onPause will be called. But
once onPause is called, Android reserves the right to kill your Activity at any point.
Unit 2

For example, here's an implementation of onPause() :

@Override
public void onPause() {
super.onPause(); // Always call the superclass method first

// Release the Camera because it is not needed when the activity is paused
// and other activities might need to use it.
if (mCamera != null) {
mCamera.release()
mCamera = null;
}
}

onStop()

onStop function is called when your Activity is no longer visible to the user. It is similar to onPause
but here you will not see your Android activity entirely.

For example, here's an implementation of onStop() :

@Override
protected void onStop() {
super.onStop(); // Always call the superclass method first

// Save the current draft, because the activity is stopping


// and we want to ensure the changes are not lost.
ContentValues values = new ContentValues();
values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());
values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());

getContentResolver().update(
mUri, // The URI for the note to update.
values, // The map of column names and new values to apply to them.
null, // No SELECT criteria are used.
null // No WHERE columns are used.
);
}

onRestart()

onRestart function is similar to onCreate, but it gets called only after onStop. This is the method
which you can use to know, if your application is starting afresh or getting restarted. onStart gets
called after onRestart.
Unit 2

For example, here's an implementation of onRestart() :

@Override
protected void onStart() {
super.onStart(); // Always call the superclass method first

// The activity is either being restarted or started for the first time
// so this is where we should make sure that GPS is enabled
LocationManager locationManager =
(LocationManager) getSystemService(Context.LOCATION_SERVICE);
boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

if (!gpsEnabled) {
// Create a dialog here that requests the user to enable GPS, and use an intent
// with the android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS action
// to take the user to the Settings screen to enable GPS when they click "OK"
}
}

@Override
protected void onRestart() {
super.onRestart(); // Always call the superclass method first

// Activity being restarted from stopped state


}

onDestroy()

onDestroy function will be called when your Activity is getting killed. This is the final call the Activity
will receive in its Lifecycle. When the user press back button on any Activity the foreground activity
gets destroyed and control will return to the previous Activity. But remember the fact, there is no
guaranty that onDestroy will be called. Only when the system is low on resources or user press the
back button or if you use finish() explicitly in your code, onDestroy gets called.

For example, here's an implementation of onDestroy() :

@Override
public void onDestroy() {
super.onDestroy(); // Always call the superclass

// Stop method tracing that the activity started during onCreate()


android.os.Debug.stopMethodTracing();
}
Unit 2

Saving Activity State


The onSaveInstanceState() method is called as your activity begins to stop. The default
implementation of this method saves 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 and can add key-value
pairs to the Bundle object.

For example:

static final String STATE_SCORE = "playerScore";


static final String STATE_LEVEL = "playerLevel";
...

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the user's current game state
savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);

// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}

You should always call the superclass implementation of onSaveInstanceState() so the default
implementation can save the state of the view hierarchy.

Restoring State of Activity


You can recover the saved state of the activity from the Bundle, when your activity is recreated after
it was previously destroyed. Both the onCreate() and onRestoreInstanceState() callback methods
receive the same Bundle that contains the instance state information.

You must check whether the Bundle is null before attempting to read it in the onCreate() method
because the system can create new instance of the activity and doesn’t have to restore it from a
destroyed activity.

For example, here's how you can restore some state data in onCreate():

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // Always call the superclass first

// Check whether we're recreating a previously destroyed instance


if (savedInstanceState != null) {
// Restore value of members from saved state
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
Unit 2

} else {
// Probably initialize members with default values for a new instance
}
...
}

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:

public void onRestoreInstanceState(Bundle savedInstanceState) {


// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);

// Restore state members from saved instance


mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
}

You should always call the superclass implementation of onRestoreInstanceState() so the default
implementation can restore the state of the view hierarchy.

Support Multiple Screen Sizes


Android runs on a variety of devices that offer different screen sizes and densities. For applications,
the Android system provides a consistent development environment across devices and handles
most of the work to adjust each application's user interface to the screen on which it is displayed. At
the same time, the system provides APIs that allow you to control your application's UI for specific
screen sizes and densities, in order to optimize your UI design for different screen configurations.
For example, you might want a UI for tablets that's different from the UI for handsets.

A set of six generalized densities:

 ldpi (low) ~120dpi


 mdpi (medium) ~160dpi
 hdpi (high) ~240dpi
 xhdpi (extra-high) ~320dpi
 xxhdpi (extra-extra-high) ~480dpi
 xxxhdpi (extra-extra-extra-high) ~640dpi

Here dpi is the unit in which the resources are been scaled like pixels. Based on these screen sizes
we have to upload bitmap files to respective drawable folders. Also you could design xml design
files for different screens and put in respective layout folders.

Gradle
Gradle is an automated build toolkit that allows the way in which projects are to be configured and
managed through a set of build configuration files.
Unit 2

This includes defining how a project is to be built, what dependencies need to be fulfilled for the
project to build successfully and what the end result (or results) of the build process should be. The
build process of Android projects is handled by the Gradle build system. If you create a new project
in Android studio, the Gradle build scripts are automatically created. Android studio wraps the
Gradle runtime, hence no additional installation is required.

The Gradle build system is designed to support complex scenarios in creating different types of
Android applications, such as:

Multi-distribution: the same application must be customized for several clients or


companies

Multi-apk: which supports the creation of multiple apks for different device types by reusing
parts of the code.

Every Android Studio project contains two kinds of Gradle build files:

Top-Level Build File where you'll find the configuration options that are common to all the
modules that make up your project.

Module-Level Build File where each module has its own Gradle build file that contains
module-specific build settings. You'll spend most of your time editing module-level build
file(s) rather than your project's top-level build file.

You might also like