Mobile Application DevelopmentUnit 317 min read
Activities, Intents, Lifecycle & Task Management in Android
Unit 3 of Mobile Application Development explores Android’s Activity components, Intent mechanisms for navigation, the Activity Lifecycle (onCreate, onStart, onResume, etc.), and Task and Back Stack management. It covers explicit vs. implicit intents, lifecycle callbacks, and how Android manages app states and transiti
TAKEAWAYS:
- An Activity is a single screen with a UI, managed by the Android system via lifecycle callbacks (e.g.,
onCreate,onPause). - Intents enable communication between Activities (explicit: direct; implicit: system-wide) and can pass data via
Intent.putExtra(). - The Activity Lifecycle determines when an Activity is visible, paused, stopped, or destroyed, affecting resource usage and state retention.
- Tasks and Back Stack manage navigation history, allowing users to return to previous Activities via the Up button or Back key.
- Lifecycle-aware components (e.g.,
ViewModel) help retain data across configuration changes (e.g., screen rotation). - Best practices include handling configuration changes properly, avoiding memory leaks, and optimizing intent filters for implicit intents.
Core Concepts: Activities and Their Role
What is an Activity?
An Activity is the entry point for a user interaction in an Android app. It represents a single screen with a UI (e.g., a login screen, a settings menu, or a chat window). Activities are managed by the Activity Manager, which handles their lifecycle and transitions.
Key Characteristics of an Activity:
- Defined in an AndroidManifest.xml file (e.g.,
<activity android:name=".MainActivity" />). - Extends the
android.app.Activityclass (orAppCompatActivityfor backward compatibility). - Can host Fragments, Views, and Adapters (covered in Unit 5).
- Communicates with other Activities via Intents.
How Activities Work: A Real-World Analogy
Think of an Activity like a waiter in a restaurant:
- The Activity (waiter) takes your order (
onCreate), serves food (onResume), and clears the table (onDestroy) when you leave. - If another customer (Activity) interrupts, the waiter pauses your order (
onPause) and resumes later (onResume). - The Back Stack is like the waiter remembering your table number so you can return after a break.
The Activity Lifecycle: Callbacks and States
The Activity Lifecycle defines 9 callback methods that Android calls to manage an Activity’s state. These callbacks help optimize performance and retain data.
Lifecycle Callbacks and States
stateDiagram-v2
[*] --> Initialized: onCreate()
Initialized --> Started: onStart()
Started --> Resumed: onResume()
Resumed --> Paused: onPause()
Paused --> Stopped: onStop()
Stopped --> Destroyed: onDestroy()
Paused --> Resumed: onResume()
Stopped --> Started: onStart()
Resumed --> Stopped: onStop()
Stopped --> Paused: onPause()
Stopped --> Destroyed: onDestroy()Key States and Callbacks:
| State | Callback | Description | Example Trigger |
|---|---|---|---|
| Initialized | onCreate() |
Called once when the Activity is first created. Initialize UI, views, and data here. | App launch or startActivity(). |
| Started | onStart() |
Called when the Activity becomes visible (but not interactive). | Returning from another Activity. |
| Resumed | onResume() |
Called when the Activity is in the foreground and interactive. | User taps on the Activity. |
| Paused | onPause() |
Called when another Activity takes focus (e.g., a dialog appears). | User opens a popup or switches Activities. |
| Stopped | onStop() |
Called when the Activity is no longer visible (e.g., user presses Home or switches Apps). | User leaves the Activity. |
| Destroyed | onDestroy() |
Called before the Activity is destroyed (e.g., system kills it for memory). | Low memory or explicit finish(). |
Worked Example: Lifecycle in a Chat App
Scenario: A user opens a WhatsApp chat (Activity A), then opens a media picker (Activity B). Activity A is paused but not destroyed.
Step-by-Step Trace:
Activity A (
onCreate):- User opens the chat app.
onCreate()initializes the chat UI and loads messages.- State: Resumed.
Activity B (
onStart,onResume):- User taps to send an image.
onPause()is called on Activity A (UI is still visible but not interactive).- Activity B starts:
onCreate()→onStart()→onResume(). - State: Activity A = Paused; Activity B = Resumed.
Return to Activity A (
onResume):- User selects an image and returns to the chat.
onPause()is called on Activity B.onResume()is called on Activity A (UI becomes interactive again).- State: Activity A = Resumed; Activity B = Stopped.
App Switch (
onStop,onDestroy):- User presses the Home button.
onPause()→onStop()on Activity A (no longer visible).- If the system kills Activity A for memory,
onDestroy()is called.
Why This Matters:
- Data Loss Prevention: Save critical data in
onPause()oronSaveInstanceState(). - Performance: Release resources (e.g., cameras, sensors) in
onStop(). - User Experience: Avoid blocking the UI in
onResume()(use background threads).
Intents: Communication Between Activities
What is an Intent?
An Intent is a messenger object that requests an action (e.g., open a camera, share text, or launch an Activity). It can be:
- Explicit: Targets a specific Activity (e.g.,
MainActivity). - Implicit: Declares a general action (e.g., "open a browser") and lets the system choose the best app.
Types of Intents
| Type | Use Case | Example |
|---|---|---|
| Explicit | Directly specifies the target Activity using its class name. | Intent intent = new Intent(this, SettingsActivity.class); |
| Implicit | Specifies an action (e.g., ACTION_VIEW, ACTION_SEND) and data type. |
Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); |
| Broadcast | Sends a system-wide message (e.g., battery low, network change). | Intent intent = new Intent("com.example.BATTERY_LOW"); |
| Service | Starts a background Service (covered in Unit 9). |
Intent intent = new Intent(this, MyService.class); |
How Intents Work: Step-by-Step
sequenceDiagram
participant User
participant ActivityA
participant AndroidSystem
participant ActivityB
User->>ActivityA: Clicks "Share" button
ActivityA->>AndroidSystem: Creates Intent (ACTION_SEND, text/plain)
AndroidSystem->>ActivityB: Delivers Intent to WhatsApp/Khalti
ActivityB->>AndroidSystem: Returns RESULT_OK or RESULT_CANCELED
AndroidSystem-->>ActivityA: Notifies resultWorked Example: Sharing Text via Intent (Khalti App)
Scenario: A user in the Khalti app wants to share a payment link.
Code Example:
// In ActivityA (e.g., PaymentSuccessActivity)
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, "Pay via Khalti: https://khalti.com/pay/12345");
startActivity(Intent.createChooser(shareIntent, "Share via"));
Step-by-Step Execution:
Intent Creation:
ACTION_SENDtells Android: "I want to share something."setType("text/plain")specifies the data format (text).putExtra()adds the payment link.
System Chooser:
- Android displays a list of apps (WhatsApp, Email, Messenger) that can handle
ACTION_SEND. - User selects WhatsApp.
- Android displays a list of apps (WhatsApp, Email, Messenger) that can handle
Activity B (WhatsApp) Receives Intent:
- WhatsApp’s
onCreate()receives the Intent viagetIntent(). - It extracts the text using
getStringExtra(Intent.EXTRA_TEXT).
- WhatsApp’s
Result Handling (Optional):
- If Activity B (WhatsApp) needs to confirm sharing, it calls:
setResult(RESULT_OK, new Intent()); finish(); - Activity A can check the result with
startActivityForResult().
- If Activity B (WhatsApp) needs to confirm sharing, it calls:
Real-World Tie-In:
- Khalti uses implicit intents to let users share payment links via any messaging app.
- Pathao uses explicit intents to open its driver app when a user requests a ride.
- Daraz uses intents to launch product details or the cart screen.
Task and Back Stack: Managing Navigation
What is a Task?
A Task is a collection of Activities grouped by the system (e.g., all Activities launched by a single user action). The Back Stack is a LIFO (Last-In-First-Out) stack that tracks the order of Activities in a Task.
Example Task Flow:
- User opens Daraz (Activity A: Home Screen).
- User taps a product → Product Details (Activity B).
- User adds to cart → Cart Screen (Activity C).
- User presses Back:
- Activity C is removed from the stack.
- Activity B becomes visible again.
How the Back Stack Works
flowchart LR
A["Daraz Home\n(Activity A)"] --> B["Product Details\n(Activity B)"]
B --> C["Cart Screen\n(Activity C)"]
C -->|"Back Press"| B
B -->|"Back Press"| A
A -->|"Home Button"| [*]Key Points:
- The Up button (or Back key) navigates the Back Stack.
- Pressing Home or Recents removes the Task from memory (unless it’s a persistent Task).
- SingleTop and SingleTask launch modes affect how Activities are added to the stack.
Worked Example: Ncell’s App Navigation
Scenario: A user checks Ncell’s balance via the app.
Launch Ncell App (Activity A: Home Screen)
- Task Stack:
[A]
- Task Stack:
Tap "Check Balance" (Activity B: Balance Screen)
- Task Stack:
[A, B]
- Task Stack:
Tap "Back"
- Activity B is finished; Task Stack:
[A]
- Activity B is finished; Task Stack:
Press Home → Reopen Ncell
- Android restores the Task Stack:
[A, B](if not cleared by the system).
- Android restores the Task Stack:
Problem: If the user rotates the screen, Android recreates Activities but retains the Task Stack.
Solution: Use android:configChanges in AndroidManifest.xml or override onSaveInstanceState().
Lifecycle-Aware Components: ViewModel and LiveData
Why Use Lifecycle-Aware Components?
Activities can be destroyed and recreated (e.g., screen rotation). To retain data:
- Use
ViewModel(scoped to an Activity/Fragment). - Use
LiveData(observes lifecycle changes).
Example: Retaining Data in a Bank App
Scenario: A user enters a Nabil Bank loan amount but rotates the screen.
Without ViewModel:
onDestroy()is called → all data inonCreate()is lost.
With ViewModel:
// In MainActivity
public class LoanActivity extends AppCompatActivity {
private LoanViewModel viewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewModel = new ViewModelProvider(this).get(LoanViewModel.class);
// Observe LiveData
viewModel.getLoanAmount().observe(this, amount -> {
editTextAmount.setText(String.valueOf(amount));
});
}
public void submitLoan(View view) {
String amount = editTextAmount.getText().toString();
viewModel.setLoanAmount(Double.parseDouble(amount));
}
}
// ViewModel class
public class LoanViewModel extends ViewModel {
private MutableLiveData<Double> loanAmount = new MutableLiveData<>();
public LiveData<Double> getLoanAmount() {
return loanAmount;
}
public void setLoanAmount(Double amount) {
loanAmount.setValue(amount);
}
}
How It Works:
- User enters
50000ineditTextAmountand rotates the screen. onDestroy()is called onLoanActivity, butViewModelsurvives.onCreate()recreates the Activity and restores theloanAmountviaLiveData.
Common Pitfalls and Best Practices
1. Memory Leaks
Problem: Holding a reference to an Activity in a static variable or non-lifecycle-aware component.
Solution: Use ViewModel or LifecycleObserver.
2. Improper Configuration Changes
Problem: Activities restart on screen rotation, losing UI state. Solution:
- Save state in
onSaveInstanceState(). - Use
ViewModelfor data. - Add
android:configChanges="orientation|screenSize"(but handle changes manually).
3. Inefficient Intent Filters
Problem: Overly broad implicit intents (e.g., android.intent.action.VIEW without constraints).
Solution: Narrow intent filters with setDataAndType() or categories.
4. Blocking the UI Thread
Problem: Long-running tasks (e.g., network calls) in onResume().
Solution: Use AsyncTask, Coroutines, or RxJava.
In the Real World
1. eSewa: Payment Flow with Intents
- Idea Used: Explicit Intents for internal navigation.
- How: When a user selects "Pay Bill," eSewa launches the
PaymentActivityvia:Intent intent = new Intent(eSewa.this, PaymentActivity.class); intent.putExtra("BILL_ID", billId); startActivity(intent); - Why: Ensures only eSewa’s
PaymentActivityhandles the intent, avoiding ambiguity.
2. Pathao: Ride Request with Implicit Intents
- Idea Used: Implicit Intents for third-party integrations.
- How: Pathao uses
ACTION_VIEWto open Google Maps for navigation:Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://maps.google.com/?saddr=" + currentLocation + "&daddr=" + destination)); startActivity(intent); - Why: Lets users choose their preferred maps app (Google Maps, Maps.me).
3. NTC’s App: Task Management for Ticket Booking
- Idea Used: Back Stack for seamless navigation.
- How: When a user books a bus ticket:
HomeActivity→SearchActivity→BookingActivity→ConfirmationActivity.- Pressing Back returns to
BookingActivity, thenSearchActivity.
- Why: Provides a consistent user experience without losing context.
4. NEPSE App: LiveData for Stock Prices
- Idea Used: Lifecycle-aware
LiveDatato update UI dynamically. - How: Stock prices update in real-time without recreating Activities on rotation.
- Code Snippet:
LiveData<String> stockPrice = viewModel.getStockPrice(); stockPrice.observe(this, price -> { textViewPrice.setText(price); });
Exam Tip
What to Expect in TU/PU Exams
Short Questions (2-5 marks):
- Define Activity, Intent, or Back Stack.
- Differentiate between explicit and implicit intents.
- List 3 lifecycle callbacks and their order.
Programming Questions (10-15 marks):
- Write code to:
- Launch an Activity with an Intent.
- Pass data between Activities using
putExtra()andgetIntent(). - Handle configuration changes with
onSaveInstanceState().
- Debug a memory leak in an Activity.
- Write code to:
Scenario-Based Questions (10-20 marks):
- Explain how WhatsApp uses Intents to share media.
- Describe the lifecycle of a Daraz product details screen when the user rotates the device.
- Design a Task Stack for a banking app with 3 Activities.
Diagram Questions (5-10 marks):
- Draw the Activity Lifecycle diagram and label all callbacks.
- Sketch the Back Stack for a given sequence of Activities (e.g., Home → Settings → Profile).
How to Score Full Marks
- For Theory: Use bullet points and tables to organize answers (examiners love clarity).
- For Code: Always include:
- The Intent creation (explicit/implicit).
- Data passing (
putExtra()). - Result handling (
startActivityForResult()if needed).
- For Diagrams: Label every state and transition (e.g., "onPause() → onStop()").
- For Scenarios: Tie answers to real apps (e.g., "Like Khalti, the app should use
ViewModelto retain payment data").
Common Mistakes to Avoid
- Forgetting
super.onCreate(savedInstanceState)inonCreate(). - Not handling configuration changes (e.g., ignoring
onSaveInstanceState()). - Using static variables to store Activity references (causes leaks).
- Overcomplicating intent filters (stick to necessary actions/categories).
Final Checklist Before the Exam
| Topic | Key Points to Remember |
|---|---|
| Activity Lifecycle | Order of callbacks: onCreate() → onStart() → onResume() → onPause() → onStop(). |
| Intents | Explicit: new Intent(this, TargetActivity.class). Implicit: ACTION_SEND, setType(). |
| Back Stack | LIFO order; use finish() to remove Activities. |
| ViewModel | Retains data across configuration changes. |
| Best Practices | Avoid memory leaks; use LiveData for UI updates. |
Based on the TU BIM syllabus for Mobile Application Development (IT272), unit 3.
Discussion
Loading…