CACS351 Mobile Programming

Mobile ProgrammingUnit 213 min read

Android Architecture & Core Components: Activities, Services, BroadcastReceivers, ContentProviders

Unit 2 of Mobile Programming: Explores Android’s layered architecture (OS, runtime, framework, apps) and its four core components (Activities, Services, BroadcastReceivers, ContentProviders), how they interact via intents, lifecycle states, and best practices for memory management and process isolation.

TAKEAWAYS:

  • Android’s architecture is a modular stack (OS → Runtime → Framework → Apps) where the Framework Layer provides APIs for Activities, Services, and more.
  • Activities manage UI screens (e.g., login, home) and follow a stateful lifecycle (onCreate → onStart → onResume → onPause → onStop → onDestroy).
  • Services run background tasks (e.g., music playback, GPS tracking) and can bind to clients via IBinder or start asynchronously.
  • BroadcastReceivers handle system-wide events (e.g., SMS, battery low) but are short-lived and must register dynamically for security.
  • ContentProviders enable shared data access (e.g., contacts, files) via URI schemes and are secured with permissions.
  • Intents are the messaging system between components, with explicit (targeted) and implicit (broadcast) types.

1. Android’s Layered Architecture

Android’s system is built on four layers, each providing abstraction and security:

graph TD
    A["OS Kernel"] --> B["Runtime: ART/Dalvik"]
    B --> C["Framework Layer: Core APIs"]
    C --> D["Apps: Your Code"]
    C --> E["Native Libraries: C/C++"]
    C --> F["Android Runtime: ART"]
    C --> G["System Libraries: SQLite, OpenGL"]

Key Components of the Framework Layer:

  • Android Runtime (ART/Dalvik): Manages Java bytecode execution and memory.
  • Core Libraries: Collections, networking, SQLite, etc.
  • Resource Manager: Handles drawables, strings, and layouts.
  • Activity Manager: Manages UI components and lifecycle.
  • Window Manager: Controls the display hierarchy.

Why This Matters:

  • The Framework Layer is where your app interacts with Android’s core systems.
  • ART (Android Runtime) replaces Dalvik for AOT (Ahead-of-Time) compilation, improving startup time and performance.

2. The Four Core Components

Each component serves a distinct purpose and follows a security model (components must declare permissions and intents explicitly).

A. Activities

Definition: A single screen with a UI (e.g., login, settings). Managed by the ActivityManagerService.

Lifecycle States:

stateDiagram-v2
    [*] --> Created
    Created --> Started
    Started --> Resumed
    Resumed --> Paused
    Paused --> Stopped
    Stopped --> Destroyed
    Resumed --> Destroyed
    Paused --> Destroyed
    Stopped --> Created

Key Methods:

Method Called When
onCreate() When the activity is first instantiated (e.g., user taps an app icon).
onStart() When the activity becomes visible (but not interactive).
onResume() When the activity is ready for user interaction.
onPause() When another activity takes focus (e.g., phone call).
onStop() When the activity is no longer visible (e.g., behind another app).
onDestroy() When the activity is being terminated (e.g., low memory).

Worked Example: Task Switching Scenario: User opens Pathao (ride-hailing app), then receives a call. The app pauses but retains data.

sequenceDiagram
    participant U as User
    participant A as Pathao Activity
    participant S as System

    U->>S: Presses Home Button
    S->>A: onPause()
    S->>A: onStop()
    U->>S: Receives Call
    S->>A: onDestroy() (if memory pressure)
    U->>S: Ends Call
    S->>A: onCreate()
    S->>A: onStart()
    S->>A: onResume()

Advantages:

  • State retention: onSaveInstanceState() saves UI state (e.g., scroll position).
  • Configuration changes: Handles screen rotations automatically.

Disadvantages:

  • Memory leaks: If you hold references to activities (e.g., static variables), they won’t be garbage-collected.
  • Fragmentation: Different Android versions may handle lifecycle differently.

B. Services

Definition: Long-running background tasks (e.g., playing music, syncing data). Can be:

  • Started: Runs until stopSelf() or stopService().
  • Bound: Clients bind via IBinder (e.g., media player controls).

Example: Music Player Service

public class MusicService extends Service {
    private MediaPlayer mediaPlayer;

    @Override
    public void onCreate() {
        mediaPlayer = MediaPlayer.create(this, R.raw.song);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        mediaPlayer.start();
        return START_STICKY; // Restart if killed
    }

    @Override
    public IBinder onBind(Intent intent) {
        return new MusicBinder();
    }

    private class MusicBinder extends Binder {
        MusicService getService() { return MusicService.this; }
    }
}

Binding a Service:

Intent intent = new Intent(this, MusicService.class);
bindService(intent, connection, Context.BIND_AUTO_CREATE);

Key Differences from Activities:

Feature Activity Service
UI Yes (single screen) No
Lifecycle Stateful (onCreate → onDestroy) Can be sticky or transient
Binding No Yes (via IBinder)
Use Case User interaction Background tasks (e.g., GPS)

Real-World Use:

  • WhatsApp’s Push Notifications: Uses a Service to handle incoming messages even when the app is closed.
  • Google Maps Navigation: A Service runs in the background to update the route while the app is paused.

C. BroadcastReceivers

Definition: Receives intents for system-wide events (e.g., BOOT_COMPLETED, SMS_RECEIVED).

Registration Types:

  1. Static (in AndroidManifest.xml):
    <receiver android:name=".MyReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>
    
  2. Dynamic (runtime):
    IntentFilter filter = new IntentFilter("com.example.MY_ACTION");
    registerReceiver(receiver, filter);
    

Example: Battery Low Alert

public class BatteryReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_BATTERY_LOW.equals(intent.getAction())) {
            Toast.makeText(context, "Low Battery!", Toast.LENGTH_LONG).show();
        }
    }
}

Security Note:

  • Static receivers can be exploited by malicious apps to trigger actions (e.g., sending SMS).
  • Dynamic receivers are safer but must be registered at runtime.

Real-World Use:

  • Khalti’s Payment Confirmation: Listens for PAYMENT_SUCCESS broadcasts to update the UI.
  • Ncell’s Call Log: Registers for CALL_LOG broadcasts to track incoming/outgoing calls.

D. ContentProviders

Definition: Enables secure data sharing between apps (e.g., contacts, files). Uses URIs to access data.

queryreadinsertwriteApp1App2ContentProviderSQLite DB
Data flow between apps and a ContentProvider (SQLite as backend).

Example: Querying Contacts

ContentResolver resolver = getContentResolver();
Cursor cursor = resolver.query(
    ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
    null,
    null,
    null,
    null
);

Key Methods:

Method Purpose
query() Fetch data via URI.
insert() Add a new record.
update() Modify existing data.
delete() Remove a record.
getType() Returns MIME type (e.g., vnd.android.cursor.item/contact).

Security:

  • Permissions: Apps must declare android.permission.READ_CONTACTS.
  • URIs: Always use ContentResolver to avoid direct database access.

Real-World Use:

  • Daraz’s Order Data: Shares order history with the Nepal Rastra Bank for tax compliance via a ContentProvider.
  • Google Photos: Uses ContentProvider to sync images across devices.

3. Intents: Messaging Between Components

Definition: A message object that describes an action to perform (e.g., open an activity, start a service).

Types:

  1. Explicit Intent: Targets a specific component (e.g., Intent intent = new Intent(this, SettingsActivity.class);).
  2. Implicit Intent: Uses an action and data type (e.g., Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://daraz.com"));).

Implicit Intent Example:

Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, "Check out Daraz!");
startActivity(intent); // Opens Gmail/SMS app

Intent Filters: Apps declare which intents they can handle in 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>

Real-World Use:

  • eSewa’s Payment Request: Uses an implicit intent to open the Khalti app for payment.
  • Pathao’s Ride Request: Sends an explicit intent to the Pathao Service to start navigation.

4. Process and Memory Management

Android uses processes to isolate components and manage memory.

Key Concepts:

  • Process Isolation: Each app runs in its own process (e.g., com.pathao vs. com.google.android.apps.maps).
  • Memory Limits: Apps are killed if they exceed OOM (Out of Memory) limits.
  • Foreground Services: Must show a notification (e.g., music player).

Example: Handling Low Memory

@Override
public void onTrimMemory(int level) {
    super.onTrimMemory(level);
    if (level == TRIM_MEMORY_RUNNING_CRITICAL) {
        // Free up memory (e.g., clear cache)
    }
}

Best Practices:

  • Use WeakReference for activities to avoid leaks.
  • Offload heavy tasks to a Service or Worker (from WorkManager).

5. Comparison Table: Core Components

Component UI? Background? Lifecycle Use Case
Activity Yes No Stateful User screens (e.g., login)
Service No Yes Sticky/Transient Background tasks (e.g., GPS)
BroadcastReceiver No No Short-lived System events (e.g., SMS)
ContentProvider No No Persistent Data sharing (e.g., contacts)

In the Real World

  1. Khalti’s Payment Flow:

    • Activity: Displays payment options (card, UPI).
    • Service: Handles tokenization of card details securely.
    • BroadcastReceiver: Listens for PAYMENT_SUCCESS to update the UI.
    • ContentProvider: Shares transaction history with NEPSE for tax reporting.
  2. NTC’s SMS Alerts:

    • BroadcastReceiver: Registers for SMS_RECEIVED to parse alerts (e.g., "Your call is coming").
    • Service: Runs in the background to forward critical alerts to the user’s preferred app (e.g., WhatsApp).
  3. Daraz’s Order Queue:

    • Activity: Shows the order list (ListView + RecyclerView).
    • Service: Updates order status in real-time via a ContentProvider.
    • Intent: Sends an implicit intent to open the Nepal Post app for shipping labels.

Exam Tip

  1. Diagrams Are Mandatory:

    • Always draw the Android architecture layers and component lifecycle diagrams.
    • Example: Show the Activity lifecycle with onCreate → onResume → onPause → onStop.
  2. Code Snippets:

    • For Activities, include onCreate() and onSaveInstanceState().
    • For Services, show both startService() and bindService() examples.
    • For BroadcastReceivers, include both static and dynamic registration.
  3. Real-World Mapping:

    • Link components to apps you know:
      • Pathao → Uses Service for navigation + Activity for UI.
      • Khalti → Uses ContentProvider for payment data + BroadcastReceiver for success/failure.
  4. Common Pitfalls:

    • Memory leaks: Avoid static references to activities.
    • BroadcastReceiver security: Prefer dynamic registration.
    • Service binding: Always unbind in onDestroy().
  5. Practical Question Patterns:

    • "Develop an app to pass data between activities" → Use Intent + putExtra().
    • "Design a service for background music" → Show onStartCommand() with START_STICKY.
    • "Explain how a BroadcastReceiver handles SMS" → Include IntentFilter and onReceive().

Final Visual: Android Component Interaction

flowchart TD
    A["User Taps App Icon"] --> B["ActivityManagerService"]
    B --> C["Activity (onCreate)"]
    C --> D["Service (onStartCommand)"]
    C --> E["BroadcastReceiver (onReceive)"]
    E --> G["SMS Intent Filter"]
    C --> H["ContentProvider (query)"]
    D --> I["IBinder (Service Binding)"]
    H --> J["Other Apps (e.g., Daraz)"]

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

Discussion

Loading…