CACS351 Mobile Programming

Mobile ProgrammingUnit 313 min read

Activities, Intents, and Event Handling in Android

Unit 3 of Mobile Programming: This note explains Android’s Activities (UI screens), Intents (message-passing between components), and Event Handling (user interactions), with code examples, visual traces, and real-world ties to apps like Pathao and Khalti.

TAKEAWAYS:

  • An Activity is a single screen with a lifecycle (onCreate → onStart → onResume) and manages UI threads.
  • Intents are Android’s messaging system: explicit (targets a specific component) vs. implicit (broadcasts to any matching component).
  • Events in Android are triggered by user actions (clicks, touches) and handled via listeners (e.g., OnClickListener).
  • Fragments are reusable UI components that can be swapped into/out of an Activity (e.g., tabbed interfaces in Daraz).
  • BroadcastReceivers handle system-wide events (e.g., battery low, SMS received).
  • Service components run in the background (e.g., music playback in YouTube).

1. Android Activities: The UI Lifecycle

An Activity is the building block of an Android app’s UI. It represents a single screen (e.g., login, home, settings) and manages its own lifecycle. Unlike web pages, Activities are stateful—they remember data even when paused (e.g., by a phone call).

Activity Lifecycle States

stateDiagram-v2
    [*] --> Created
    Created --> Started
    Started --> Resumed
    Resumed --> Paused
    Paused --> Stopped
    Stopped --> Destroyed
    Resumed --> Destroyed
    Paused --> Destroyed
    Stopped --> Resumed
    Paused --> Resumed
    Stopped --> Paused
startonStart()onResume()onPause()onDestroy()onStop()onRestart()onRestart()onRestart()createdstartedresumedpausedstoppeddestroyed
State transitions with lifecycle callbacks (arrows show possible paths)

Key Methods:

Method Triggered When
onCreate() Activity is first created (initializes UI).
onStart() Activity becomes visible (but not interactive).
onResume() Activity is ready for user interaction (topmost screen).
onPause() Activity loses focus (e.g., another app opens).
onStop() Activity is no longer visible (e.g., minimized).
onDestroy() Activity is being terminated (e.g., user closes it).

Example: Activity Lifecycle Trace

Consider an Activity that opens a Khalti payment screen:

  1. User taps "Pay" → onCreate() initializes the UI (payment form).
  2. Activity becomes visible → onStart().
  3. User starts typing → onResume() (ready for input).
  4. User taps "Back" → onPause() (payment screen fades out).
  5. System kills the process → onStop() → onDestroy() (data saved to onSaveInstanceState).

Code Example: Basic Activity

public class PaymentActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.payment_layout); // Load UI
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d("PaymentActivity", "User can now interact!");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d("PaymentActivity", "Saving payment progress...");
    }
}

Trace Table:

Step Method Called State Change
App starts onCreate() Created → Started
User taps "Pay" onStart() → onResume() Started → Resumed
User taps "Back" onPause() Resumed → Paused
System kills app onStop() → onDestroy() Paused → Destroyed

2. Intents: Messaging Between Components

Intents are Android’s inter-process communication (IPC) system. They let components (Activities, Services, BroadcastReceivers) send data to each other. There are two types:

A. Explicit Intents

Target a specific component by its class name (e.g., opening a Pathao driver’s profile from the app).

Intent intent = new Intent(this, DriverProfileActivity.class);
intent.putExtra("driver_id", "DRV123");
startActivity(intent);

B. Implicit Intents

Broadcast a general action (e.g., "share text") and let Android find a matching component (e.g., WhatsApp, Facebook).

Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, "Check out this deal!");
startActivity(Intent.createChooser(shareIntent, "Share via"));

Intent Filters (for Implicit Intents)

Components declare which intents they can handle via AndroidManifest.xml:

<activity android:name=".ShareActivity">
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="text/plain" />
    </intent-filter>
</activity>

Worked Example: Sending Data Between Activities

Scenario: A Daraz product detail screen sends the selected item to a cart Activity.

flowchart TD
    A["ProductDetailActivity"] -->|"Explicit Intent"| B["CartActivity"]
    A -->|"putExtra('item', product)"| B
    B -->|"onCreate()"| C["Update Cart UI"]
    B -->|"onNewIntent()"| D["Update Cart UI (if changed)"]

Code:

// In ProductDetailActivity.java
Button addToCart = findViewById(R.id.add_to_cart);
addToCart.setOnClickListener(v -> {
    Intent intent = new Intent(ProductDetailActivity.this, CartActivity.class);
    intent.putExtra("item", product); // Serialize product data
    startActivity(intent);
});

// In CartActivity.java
@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    Product product = (Product) intent.getSerializableExtra("item");
    updateCartUI(product);
}

Trace:

  1. User taps "Add to Cart" → ProductDetailActivity creates an Intent.
  2. startActivity() launches CartActivity with the product data.
  3. CartActivity.onNewIntent() updates the cart UI.

3. Event Handling in Android

Events are user interactions (clicks, touches, gestures) or system notifications (e.g., battery low). Android handles them via listeners.

A. Common Event Sources

Event Source Example Trigger Handler Class
Button User taps a button OnClickListener
TextView User types in an EditText TextWatcher
System Phone call, SMS received BroadcastReceiver
Sensor Device motion (accelerometer) SensorEventListener

B. Example: Handling a Button Click

Scenario: A Khalti "Pay Now" button triggers payment processing.

Button payButton = findViewById(R.id.pay_now);
payButton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        // 1. Validate input
        String amount = editTextAmount.getText().toString();
        if (amount.isEmpty()) {
            Toast.makeText(PaymentActivity.this, "Enter amount!", Toast.LENGTH_SHORT).show();
            return;
        }

        // 2. Launch payment screen
        Intent intent = new Intent(PaymentActivity.this, PaymentScreenActivity.class);
        intent.putExtra("amount", amount);
        startActivity(intent);
    }
});

C. Asynchronous Events: BroadcastReceivers

Scenario: A Ncell app notifies when the user’s balance is low.

public class BalanceReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals("android.provider.Telephony.BALANCE_LOW")) {
            String balance = intent.getStringExtra("balance");
            Toast.makeText(context, "Low balance: " + balance, Toast.LENGTH_LONG).show();
        }
    }
}

Register in AndroidManifest.xml:

<receiver android:name=".BalanceReceiver">
    <intent-filter>
        <action android:name="android.provider.Telephony.BALANCE_LOW" />
    </intent-filter>
</receiver>

4. Fragments: Reusable UI Components

A Fragment is a modular piece of an Activity’s UI (e.g., a tab in Daraz). It can be:

  • Added/detached dynamically.
  • Swapped between Activities.
  • Reused across multiple screens.

Why Use Fragments?

Feature Activity Fragment
Reusability No (entire screen) Yes (swappable)
State Management Manual (onSaveInstanceState) Automatic (onSaveInstanceState)
Multi-pane Layouts Clunky (e.g., resizing) Smooth (e.g., tablet vs. phone)

Example: Tabbed Interface with Fragments

Scenario: A Pathao app uses Fragments for "Ride", "Profile", and "Settings" tabs.

flowchart TD
    A["MainActivity"] --> B["FragmentContainerView"]
    B --> C["RideFragment"]
    B --> D["ProfileFragment"]
    B --> E["SettingsFragment"]
    C -->|"User taps"| D
    D -->|"User taps"| E
    E -->|"User taps"| C

Code:

// In MainActivity.java
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        BottomNavigationView navView = findViewById(R.id.nav_view);
        navView.setOnNavigationItemSelectedListener(navListener);
    }

    private BottomNavigationView.OnNavigationItemSelectedListener navListener
        = item -> {
            Fragment selectedFragment = null;
            switch (item.getItemId()) {
                case R.id.nav_ride: selectedFragment = new RideFragment(); break;
                case R.id.nav_profile: selectedFragment = new ProfileFragment(); break;
                case R.id.nav_settings: selectedFragment = new SettingsFragment(); break;
            }
            getSupportFragmentManager().beginTransaction()
                .replace(R.id.fragment_container, selectedFragment)
                .commit();
            return true;
        };
}

5. Comparing Components: Activity vs. Service vs. BroadcastReceiver

Component Purpose Runs on UI Thread? Lifecycle Example Use Case
Activity Displays UI to the user Yes Tied to a screen Login screen in Khalti
Service Runs background tasks No Long-lived (until stopped) Music playback in YouTube
BroadcastReceiver Handles system-wide events No Short-lived (per event) Battery low notification in Ncell

In the Real World

  1. Pathao (Ride-hailing App)

    • Intents: Uses explicit intents to launch the driver’s profile from the ride details screen.
    • Fragments: Implements a tabbed interface (Ride History, Profile, Settings) using Fragments for smooth transitions.
  2. Khalti (Payment Gateway)

    • Event Handling: The "Pay Now" button triggers a click listener that validates input and launches the payment screen via an Intent.
    • Activity Lifecycle: Saves payment progress in onSaveInstanceState() to handle screen rotations.
  3. Daraz (E-commerce)

    • Fragments: Dynamically swaps Fragments for product details, cart, and checkout flows.
    • Implicit Intents: Uses ACTION_SEND to share product links via WhatsApp or Facebook.

Worked Example: Daraz Order Queue Imagine Daraz uses a Service to process orders in the background while the user browses:

  1. User adds items to cart → CartActivity starts a OrderProcessingService.
  2. Service runs asynchronously, updating the cart via LocalBroadcastManager.
  3. If the user rotates the screen, the Activity restarts but the Service continues processing.

Exam Tip

  • Focus on:
    • Activity lifecycle methods (onCreate, onResume, onPause). Always trace state changes.
    • Intent types: Know when to use explicit vs. implicit intents (e.g., opening a specific Activity vs. sharing text).
    • Event listeners: Practice writing OnClickListener and TextWatcher for buttons and EditTexts.
    • Fragments: Understand how to replace Fragments dynamically and handle configuration changes.
  • Common Pitfalls:
    • Forgetting to save state in onSaveInstanceState() (e.g., for Activities that handle screen rotations).
    • Misusing Services (they should not block the UI thread; use AsyncTask or HandlerThread).
    • Overcomplicating Intents—start with explicit intents before using implicit ones.
  • Code Practice:
    • Write a Fragment that displays data from an Activity.
    • Implement a BroadcastReceiver to handle a custom event (e.g., "user logged in").
    • Trace the lifecycle of an Activity that opens another Activity via an Intent.
Explicit IntentsendBroadcast()startService()LocalBroadcastManagerActivityAActivityBBroadcastReceiverService
Event flow: Activity → Activity → BroadcastReceiver → Service (with fallback to LocalBroadcastManager)

Visual Summary:

Based on the TU BCA syllabus for Mobile Programming (CACS351), unit 3.

Discussion

Loading…