Friday, 20 September 2013

Applying Style in android

A style is a set of one or more formatting attributes that you can apply as a unit to single elements in your layout XML file(s). For example, you could define a style that specifies a certain text size and color, then apply it to instances of a certain type of View element.

details>>

Create a dummy Android Application, AndroidStyle. Create style.xml in the folder res > values


<?xml version="1.0" encoding="utf-8"?>
<resources>
 <style name="StyleText1">
     <item name="android:textSize">20sp</item>
     <item name="android:textColor">#EC9200</item>
     <item name="android:gravity">center_horizontal</item>
 
 </style>
 <style name="StyleText2">
     <item name="android:textSize">30sp</item>
     <item name="android:textColor">#990000</item>
     <item name="android:gravity">right</item>
 </style>
 <style name="StyleButton1">
     <item name="android:layout_width">wrap_content</item>
     <item name="android:layout_height">wrap_content</item>
 </style>
 <style name="StyleButton2">
     <item name="android:layout_width">fill_parent</item>
     <item name="android:layout_height">fill_parent</item>
 </style>    
</resources>


Modify main.xml to apply the styles.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 >
<TextView
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:text="@string/hello"
 />
<TextView
 style="@style/StyleText1"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:text="It's StyleText1"
 />
<TextView
 style="@style/StyleText2"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:text="It's StyleText2"
 />
<Button
 style="@style/StyleButton1"
 android:text="It's StyleButton1"
 />
<Button
 style="@style/StyleButton2"
 android:text="It's StyleButton2"
 /> 
</LinearLayout>


Hierarchy Viewer

The Hierarchy Viewer application allows you to debug and optimize your user interface. It provides a visual representation of the layout's View hierarchy (the Layout View) and a magnified inspector of the display (the Pixel Perfect View).

To get the Hierarchy Viewer started:

1. Connect your device or launch an emulator.
2. From a terminal, launch hierarchyviewer from your SDK /tools directory.
3. In the window that opens, you'll see a list of Devices. When a device is selected, a list of currently active Windows is displayed on the right. The "focused window" is the window currently in the foreground, and also the default window loaded if you do not select another.
4. Select the window that you'd like to inspect and click Load View Hierarchy. The Layout View will be loaded. You can then load the Pixel Perfect View by clicking the second icon at the bottom-left of the window.

If you've navigated to a different window on the device, press Refresh Windows to refresh the list of available windows on the right.


Example of using PopupMenu

Android 3.0(API Level 11) provide android.widget.PopupMenu class, to displays a Menu in a modal popup window anchored to a View. The popup will appear below the anchor view if there is room, or above it if there is not. If the IME is visible the popup will not overlap it until it is touched. Touching outside of the popup will dismiss it.

Example of using PopupMenu

Create a file /res/menu/popupmenu.xml to define the PopupMenu.
<menu xmlns:android="http://schemas.android.com/apk/res/android">
  <group android:id="@+id/group_popupmenu">
      <item android:id="@+id/menu1"
          android:title="Popup menu item 1"/>
      <item android:id="@+id/menu2"
          android:title="Popup menu item 2"/>
      <item android:id="@+id/menu3"
          android:title="Popup menu item 3"/>
  </group>
</menu>


Main Java code
package com.AndroidPopupMenu;

import android.app.Activity;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.PopupMenu;
import android.widget.TextView;
import android.widget.Toast;

public class AndroidPopupMenuActivity extends Activity {
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
    
      Button button = (Button)findViewById(R.id.button);
      TextView text = (TextView)findViewById(R.id.text);
      ImageView image = (ImageView)findViewById(R.id.image);
    
      button.setOnClickListener(viewClickListener);
      text.setOnClickListener(viewClickListener);
      image.setOnClickListener(viewClickListener);
    
    
  }

  OnClickListener viewClickListener
  = new OnClickListener(){

  @Override
  public void onClick(View v) {
   // TODO Auto-generated method stub
   showPopupMenu(v);
  }
   
  };

  private void showPopupMenu(View v){
   PopupMenu popupMenu = new PopupMenu(AndroidPopupMenuActivity.this, v);
      popupMenu.getMenuInflater().inflate(R.menu.popupmenu, popupMenu.getMenu());
    
      popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
   
   @Override
   public boolean onMenuItemClick(MenuItem item) {
    Toast.makeText(AndroidPopupMenuActivity.this,
      item.toString(),
      Toast.LENGTH_LONG).show();
    return true;
   }
  });
    
      popupMenu.show();
  }
}


Main layout, main.xml
<?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="vertical"
  android:gravity="center_horizontal">

  <TextView
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:text="@string/hello" />
  <Button
      android:id="@+id/button"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="A Button"
      />
  <TextView
      android:id="@+id/text"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="A TextView"
      />
  <ImageView
      android:id="@+id/image"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:src="@drawable/ic_launcher"
      />

</LinearLayout>

Tuesday, 17 September 2013

Android Activity and Service Life-cycle notes

Android Activity and Service Life-cycle notes

Hello,
In the past, there have been many times that Activity or Service lifecycle confuse me, and I usually have to go back to the corresponding Android SDK documentation pages, which are very analytic and helpful (of course!). In order to clarify what I need to implement, sometimes I have to read the whole document, until I find what I need, making me read stuff that I have already passed through in the past. So, I decided to keep some notes, which I will present here for future reference, and who knows, these might help you! Some parts are written in my own words, while others have been copied from the Android SDK documentation.
Activity Life-cycle
onCreate: This is where the UI is defined. This method is called only the first time that the activity instance is launched and when it has been dropped by the system
onPause: User is leaving the activity, so any changes made, should be committed
onStart: Class members are still alive, as the class was just stopped, so the memory costy resources that have been released, should be re-initialized at this state.
onDestory: Activity is finishing or being destroyed by the system.
Entrire Lifetime:
- Between the onCreate and onDestroy events
Visible Lifetime
- Between the onStart and onStop events
Foreground Lifetime
- Between the onResume and on Pause events. An application might pass frequently from these stages, so no heavey load should be performed during these transitions.
Status transitions:
1. Activity at the top of the stack is active or running
2. Activity lost focus but is still visible, when is paused. Can be killed by the system in extreme low memory situations.
(it maintains all state and member information)
3. Activity has been completely obscured by another activity, then its stopped. It is no longer visible to the user so its
window is hidden and it will often be killed by the system when memory is needed elsewhere.
(it maintains all state and member information)
4. While an activity being in paused or stopped state, it might be dropped by the system, in order to release memory. When viewed again, it has to be completely restarted from its previous state.
Coordinating activities:
- Activity A’s onPause() method executes.
- Activity B’s onCreate(), onStart(), and onResume() methods execute in sequence. (Activity B now has user focus.)
- Then, if Activity A is no longer visible on screen, its onStop() method executes.
Note that it is important to save persistent data in onPause() instead ofonSaveInstanceState(Bundle) because the latter is not part of the lifecycle callbacks. This method  is called before placing the activity in such a background state, allowing you to save away any dynamic instance state in your activity into the given Bundle, which will be passed to the new object through the onCreate(Bundle) method, if the activity needs to be re-created.
Service Life-cycle
onCreate: service is instantiated and setup
onStartCommand(Intent, int, int): service receives a call via startService.
onDestroy: when an activity calls stopService, or the service itself calls stopSelf, or the system decides to destroy the service.
* Using binding, an Activity can connect to a Service and make direct  calls back to the service. This is another method of using services, which cannot be covered in this post. This method of starting and accessing a Service affects the life cycle of the Service.
Two modes of operation depending on the value returned by the onStartCommand method:
- constant START_STICKY is used for services that are explicitly started and stopped as needed.
- constants START_NOT_STICKY or START_REDELIVER_INTENT are used for services that should only remain running while processing any commands sent to them.
That’s all for now. I have also attached the life-cycle describing diagrams from Android SDK documentation.
Happy android coding


Sunday, 15 September 2013

Android Activities and Tasks series – Activity Attributes

In this post, we focus on activities themselves and explain theproperties we can set on an activity or task to influence the activity launch behavior on the receiver side. In detail:
  1. activity launch modes
  2. task attributes
  3. task affinities of activities

Introduction

In Android, every activity must be defined in the project’sAndroidManifest.xml file, using activity tags placed as children of the application tag. Here, a set of attributes can be specified for each activity. The only mandatory attribute is android:name, which defines the fully qualified name of the activity’s implementation class. This class must be a subclass of Activity. To avoid full qualification of the name, you can use the special “.” prefix, which will be interpreted by Android as the package name of the activity’s application. An example:
1
<activity android:name=".MyActivity" />

Launch Modes

The intent flags (defined on the calling intent) in conjunction with the launch mode (specified on the called activity) define the actual outcome of the launch. There are four different launch modes: standard,singleTopsingleTask and singleInstance. The first two only have an impact on the activity, while the last two have important consequences for the task the activity should run in.

standard

A new instance of the activity is created and pushed on top of the current task. The created instance will receive the intent. This is thedefault and most commonly used behavior.

singleTop

Launch Mode "singleTop"
Behaves exactly like standard, with one important exception: If an instance of the same activity is already on top of the task stack, then this instance will be reused to respond to the intent. No new activity instance is created. Note that, if such an instance is present in the stack, but not at the top, the behavior is identical to launch modestandard and will thus result in a new instance being created.
Although the callback onResume(..) is invoked on that activity instance, take note that getIntent() will still return the original intent, not the new intent! Thus, to receive the new intent, a singleTop activity must implement the method onNewIntent(Intent). This method is invoked by Android upon launch with the new intent object as parameter.
Using singleTop within an application is useful to avoid starting the same activity multiple times in a row. It will not enforce that you have only one instance of a certain activity type in one task stack, because an activity instance is only reused if it is at the top of the stack.

singleTask

Launch Mode "singleTask"
The activity is always started in a new task. Thus, a singleTask activity will always be the root activity of a task. Activities launched from this activity will be put on top of the new task’s stack by default.
Moreover, a singleTask activity acts as a singleton, i.e. it is impossible to have a second instance of such an activity, neither in this task nor in any other task. Upon launching the activity a second time, the intent is delivered to the existing instance via onNewIntent(Intent).
This behavior is useful for activities that act as entry points to your application. With this, you can enforce that these always start in a new task. At the same time, you ensure that the activity is never instantiated a second time and intents are delivered to the already existing activity.

singleInstance

Launch Mode "singleInstance"
Behaves exactly like singleTask but never allows other activities to become part of the new task. The activity will remain the sole activity instance in the task. As soon as another activity is started from here, the new activity will be automatically assigned to a different task, just like the intent would have FLAG_ACTIVITY_NEW_TASK set.
Use cases of this mode are rare. Any activity started from yoursingleInstance activity will be placed in another task. Thus, when the user returns to your singleInstance task, activities from the new task are not resumed and presented to the user, which is not desirable in the majority of cases.
It is useful for portal-like apps that only start activities from other applications, making it unnecessary to specifyFLAG_ACTIVITY_NEW_TASK for all your intents and enabling the user to resume your portal app from the home screen without resuming activities that were started from there (as these will be put in other tasks automatically).

Task Attributes

Besides for activities, Android allows you to set properties for tasks in order to customize the way the task should behave. These particular properties are therefore associated with a task and not an activity. But, as there is no direct representation of a task in the manifest XML structure, task attributes are defined as an attribute of the activity that is used as the root of this task. Thus, such a task property is only effective if it is defined on a task’s root activity; it is ignored in all other cases.
Android supports the following task attributes:

alwaysRetainTaskState

Normally, a task may be cleared by Android, meaning all activities besides the root activity are destroyed and removed from the task’s stack. After the clear has taken place, the user will see the task’s root activity when bringing the task to the foreground.
If a task has not been used in a while, Android automatically clears it. The assumption here is that, given that the task remained in the background for some time, the user is no longer interested in the activities she had navigated to. Instead, she wants to start at the root activity when bringing the task to the foreground.
The attribute alwaysRetainTaskState is a boolean value to prevent Android from clearing a task. If set to true, the activities on top of the root activity are always kept. This can be useful for tasks that carry a lot of state, like the tabs of a web browser, where you assume that the user wants to retain the state. Be aware that, as Android can no longer clear the task, the system may decide to kill your app entirely in order to reduce memory consumption.
The default is false.

clearTaskOnLaunch

When this boolean attribute is set to true, a task will be clearedeverytime it is relaunched from the home screen. All activities on top of the root activity are removed. This means that, on relaunch, the task state is always discarded and the root activity is displayed to the user.
Thus, upon relaunch and when using this mode, activities on top of the root activity are usually finished. However, note that there is an important exception: If a to-be-removed activity allows reparenting (via attribute allowTaskReparenting) and this activity has an affinity for a different existing task, the activity will be moved to that task instead of being finished. We will address the topic of task reparenting and activity affinities in a minute.

Other task-related attributes

The following attributes are task-related, but define behavior for activities. As such, you can set them on any activity, not just on root activities.

finishOnTaskLaunch

If this boolean attribute is set to true, the activity is finished when the task is relaunched from the home screen. With this, you can mark an activity as irrelevant for the task state, meaning that we do not need to wait for Android to perform a task clean in order to forget this particular activity instance. Note, however, that the activity is not finished when bringing the task to the foreground using the list of recently started activities (by pressing and holding the home key).

noHistory

If this boolean attribute is set to true, the activity instance never remains in the task stack. As soon as the user navigates away from it, the activity instance is immediately finished, and the user cannot return to it.
This does not only mean that the activity is no longer in the task stack upon returning (i.e. relaunching the app or resuming via the list of recently started activities). The user will also never be able to return to it via the back key.

Task Affinities

Every activity has a so-called affinity for a certain task. You can think of an affinity as the name of a task this activity shall run in. By default, all activities within the same application are affine to the same task.
The task affinity of an activity has two consequences:

(1)

When launching the activity with the intent flagFLAG_ACTIVITY_NEW_TASK, Android looks for an already running task fitting this affinity, more precisely, a task whose root activity has the same affinity. If such a task exists, it is brought to the front, and the launched activity is pushed on top of its stack. If such a task does not exist, a new one is created, and activities launched at a later time will be put into this task, given that FLAG_ACTIVITY_NEW_TASK is used and the activity’s affinity is the same.
Example
Task Affinities: Launch new activities into an existing task
Suppose you are listening to a song within a music player application while have a running web browser application in the background. Now, you want to visit the website of the artist of the music track you are listening to. Let’s suppose that the music player fires an intent withFLAG_ACTIVITY_NEW_TASK to view the artist’s website inside a browser activity.
In our example, the browser application is already running in the background. As the browser activity belongs to the browser application and, as such, has an default affinity for the task the browser was launched into, the affinity will imply that the artist’s website will be displayed in a new activity that is pushed on the stack of the browser task, not the music player task.

(2)

If the activity’s property allowTaskReparenting is set to true, the activity can move from one task to another, namely from the one it was started in to the one it has an affinity for. This happens if this particular task is brought to the foreground, and an instance of our activity is present in another task at that time. Then, this activity is moved to the task that is coming to the front, and pushed on top of its stack.
Example
Task Affinities: Reparenting
Suppose you have a browsing activity that allows task reparenting and is capable of showing the contents of a web page. The activity is part of the browser application. Now, this activity is started from another application, your music player, to show the website of your favorite artist. Assuming the flag FLAG_ACTIVITY_NEW_TASK is not set, this will imply that the activity becomes part of the music player’s task.
If we now open the browser application, the activity (which has task reparenting enabled) will move from the music player task into the browser task. Why is that? Remember that the activities within an application share an affinity for the same task, which is why the browser activity is affine to the already existing browser task. Thus, upon opening the browser application, we are presented with the artist’s webpage we viewed earlier from within the music player application, and the browser activity is now on top of the browser task’s stack.
Android defines the following affinity-related attributes for activities:

android:taskAffinity

An arbitrary string to define the task affinity; more specifically, the name of the task the activity preferrably runs in. When launched with intent flag FLAG_ACTIVITY_NEW_TASK, the activity is then put into this particular task, if present. Also, this value is used to determine the target activity for task reparenting.
The default value is the package name of the application this activity is defined in, which is why activities of the same application share an affinity for the same task by default.

android:allowTaskReparenting

A boolean value to allow or prohibit task reparenting. If set to true, running activities may be moved to the task they have an affinity for once this task is brought to the foreground.

Conclusion

In this post, we have seen that not only the caller of an activity can alter the launch behavior of an activity. Customizations of that behavior can also be defined on the receiver’s end, by setting a particular launch mode on an activity. In addition, we may influence the behavior of tasks by defining task attributes on them. Moreover, through usage of activity affinities, we can group related activities to allow Android to put them into the same task, if possible.

Android Activities and Tasks series – Intent flags

In this post of the series, we focus on Android’s intent concept and address the following questions:
  1. What are intents?
  2. How do we use them to launch activities?
  3. What options (flags) does Android provide to customize this launch? (e.g. in terms of target task or activity instance creation)

In order to ease understanding of intents and their various flags, akquinet Modular and Mobile Solutions provides an Android application to experiment with intent flags. With it, you can start different types of activities, specifying the intent flags you want to pass, and examine the effects. Install it by pointing your Android browser to this URL.

Intents and activity launching

An intent is a data structure containing a description of a to-be-performed operation. This operation primarily consists of an action and of data to operate on, although there are various optional parameters to describe the operation in more detail. Technically speaking, this action is just a constant, either a pre-defined one from Android, likeACTION_VIEW or ACTION_EDIT, or a custom one that we can define ourselves.
An intent is always handled by an Android component, namely an activity, a service or a broadcast receiver. In this blog post series, we will focus on activities as intent handlers. For our purposes, an intent is used to launch an activity.
To create an intent and launch an activity with it, we can write the following code within our caller activity:
1
2
3
Intent intent = new Intent(Intent.ACTION_VIEW,
    Uri.parse("http://www.akquinet.com/")
startActivity(intent);
In this example, we give two parameters to the Intent constructor: The action to be performed (here view) and the corresponding data(here a web page URL). Then, we simply pass the Intent object tostartActivity(Intent). Basically, what we do here is telling Android that we want to view the akquinet homepage. Android will look for activities capable of handling that intent, which in this case is aweb browser activity, and start it. Note that any activity can be declared capable of handling certain intent types by defining intent filters in the application’s AndroidManifest.xml file.
Instead of letting Android choose a suitable activity, an intent may also name the to-be-launched target activity explicitly by specifying the target activity’s class, like so:
1
2
Intent intent = new Intent(this, MyActivity.class);
startActivity(intent);
When run, this code snippet has the following consequences:
  1. A new instance of MyActivity is created
  2. The instance is pushed on top of the current task’s stack, which is the one the calling activity is in.
  3. The activity is started and brought to the foreground.

Customizing the launch of activities via intent flags

The described behavior can be modified by specifying intent flags on the intent instance before passing the intent tostartActivity(Intent), for example:
1
intent.addFlag(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
This will bring an existing instance of the called activity type present in the current stack to the foreground (if there is such an instance) instead of creating a new instance. Android 2.0 defines various intent flags, which are now explained in more detail.
FLAG_ACTIVITY_BROUGHT_TO_FRONT
This flag is set by the system as an indication that an existing activity with launch mode singleTask has been called and reused. Activity launch modes are discussed in more detail in the next blog post.
FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
Bringing a task to foreground after using flag CLEAR_WHEN_TASK_RESET
This flag marks the called activity and all activities put on top of it to be cleared (removed from the stack) when the task is reset. This reset is performed as soon as the task is brought to the foreground usingFLAG_ACTIVITY_RESET_TASK_IF_NEEDED, which is always set by the system when the user resumes a task from the home screen, the main menu or the list of recently started activites.
You can use this to define a point in the task stack from where all started activities should be “forgotten” once the task is sent to the background.
FLAG_ACTIVITY_CLEAR_TOP
Using flag CLEAR_TOP to launch an activity
If there is already an instance of the called activity type present in the stack, then this instance is brought to the foreground instead of creating a new instance. Also, all activities in the stack that reside on top of that instance are cleared from the stack. For example, assuming that the current activity stack is ABCDE, launching an activity of type Cwill clear activities D and E from the task and result in the stack ABC.
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
Normally, when launching an activity in a new task, the target activity is shown in the list of recently launched activities (accessible via long press of the home button). For example, this is the case when launching the browser from your activity to render a web page. Using this flag, we can suppress that behavior, effectively excluding the target activity from the list of recently launched activities.
FLAG_ACTIVITY_FORWARD_RESULT
By default, in order for an activity B to be able to propagate a result back to the calling activity AA has to use the methodstartActivityForResult(Intent) instead of methodstartActivity(Intent) to start B. When B defines its result viasetResult(int resultCode) and finishes, the callback methodonActivityResult() is called on A where the result can be retrieved.
Resulting forwarding with Flag FORWARD_RESULT
Suppose now that B calls another activity C, which defines the result, and we want to forward that result back to A. In order to avoid having to pass results manually from B to A, Android provides this flag.
In our example, this means that B calls C, specifying the forward flag and using startActivity(Intent)C may then define a result, which is forwarded back to A automatically once C and B are finished. The callback method onActivityResult() is called on A but not called on the intermediate activity B as B only forwards the result instead of explicitly handling it.
Note that the flag may only be used in conjunction withstartActivity(Intent), not withstartActivityForResult(Intent), because an activity using the latter method marks the end of a forwarding chain and should handle the result in its callback method.
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
This flag is set by the system as an indication that an activity has been launched from the list of recently launched activities.
FLAG_ACTIVITY_MULTIPLE_TASK
This flag has no effect unless used in conjunction withFLAG_ACTIVITY_NEW_TASK. If used together, a new task is always created and a new instance of the called activity type becomes the first (and at that time, the only) element of that task.
FLAG_ACTIVITY_NEW_TASK
If this flag is used on its own (withoutFLAG_ACTIVITY_MULTIPLE_TASK), a new task is only created if there is not already a task present that the target activity has an affinity for (task affinities are examined more closely in the next blog post). If such a task already exists, the activity is put into that task instead of creating a new one.
As all activities specified within the same application have a default affinity to remain in the same task (this can be customized), starting an activity defined in the same application as the calling activity using this flag will not create a new task, unlessFLAG_ACTIVITY_MULTIPLE_TASK is specified as well.
FLAG_ACTIVITY_NO_ANIMATION
Introduced with Android 2.0, this flag disables the usual animation accompanied by an activity transition. For example, this can be used to call an activity that itself launches another activity without further user interaction, resulting in only one transition animation to be shown instead of two.
FLAG_ACTIVITY_NO_HISTORY
This flag implies that the called activity is not kept in the task’s stack. When navigating away, the user cannot return to it. For example, this is useful to launch activities that perform an immediate dispatch to another activity. This activity is consequently skipped if the user presses the back button as it is not kept in the stack.
FLAG_ACTIVITY_NO_USER_ACTION
This flag may be used as an indication that the activity transition is not an action directly performed by the user but rather an automatic one. For example, this is true for the call-in activity that is automatically launched when the device receives a phone call. Technically, it means that the invocation of callback method onUserLeaveHint() on the caller activity is suppressed.
FLAG_ACTIVITY_REORDER_TO_FRONT
Starting an activity with Flag REORDER_TO_FRONT
If there is already an instance of the called activity type present in the task stack, that instance is brought to the foreground while the rest of the stack is kept intact. This effectively reorders the stack. For example, assuming that the current activity stack is ABCDEF, launching an activity of type C using this flag will result in the new stack ABDEFC.
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
This flag has no effect unless the intent creates a new task or brings an existing task to the foreground. In that case, the task is reset, meaning that task affinities are applied (resulting in activities being moved from or to this task) and that, given thatFLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET is set as well, the task is cleared according that flag’s specification.
FLAG_ACTIVITY_SINGLE_TOP
If an instance of the target activity is already at the top of the stack, no new instance is created.

Conclusion

The akquinet Mobile and Modular Solutions provides an Android application to help you understand the effects of the intent flags. It lets you start exemplary activities using arbitrary intent flags and inspect the effects on the resulting task stack.
Intent Flags Tool - Main screen
Intent Flags Tool - Main screen
Intent Flags Tool - Selecting Flags
Intent Flags Tool - Selecting Flags
You can download the tool here. The source code is also available ongithub.
All described behavior not only depends on intent flags specified, but also on attributes defined on the called activity type (inAndroidManifest.xml), including task affinities and launch modes. While intent flags are specified by the caller, launch modes and affinities are properties of the callee. Those will be discussed in the next post of this series.