An Activity is a single, focused screen that users interact with. Android manages activities through a lifecycle — a series of callback methods triggered as the activity enters, exits, or returns to the foreground.
Why does lifecycle matter?
Save user data before the app is killed
Release resources (camera, sensors) when not needed
[App launched]
↓
onCreate() ← Activity is being created (set layout here)
↓
onStart() ← Activity becomes visible (but not interactive yet)
↓
onResume() ← Activity is in foreground & user can interact
↓
[User presses Home / Receives call / Another activity opens]
↓
onPause() ← Activity partially visible (stop animations, release heavy resources)
↓
onStop() ← Activity no longer visible
↓
[User returns to activity]
↓
onRestart() ← Called only if activity was stopped (not destroyed)
↓
onStart()
↓
onResume()
↓
[System kills activity to free memory (rare)]
↓
onDestroy() ← Final call before activity is destroyed
Activities have many useful methods beyond lifecycle callbacks:
Method
Purpose
Example
setContentView()
Set layout XML
setContentView(R.layout.activity_main)
findViewById()
Get view by ID (Kotlin: use view binding)
findViewById<TextView>(R.id.title)
finish()
Close the activity
finish() (returns to previous screen)
startActivity()
Start a new activity
startActivity(intent)
startActivityForResult()
Deprecated — use ActivityResultLauncher
See modern API below
getIntent()
Get the Intent that started this activity
val intent = intent
setResult()
Return result to previous activity
setResult(RESULT_OK, dataIntent)
onBackPressed()
Handle back button press
Override for custom behavior
moveTaskToBack()
Send app to background (like Home button)
moveTaskToBack(true)
Modern API: registerForActivityResult() (replaces startActivityForResult)
Kotlin — Activity Result API// In MainActivity
private val getResultLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == RESULT_OK) {
val data = result.data?.getStringExtra("returned_data")
Toast.makeText(this, "Returned: $data", Toast.LENGTH_SHORT).show()
}
}
// Later, launch the activity
val intent = Intent(this, SecondActivity::class.java)
getResultLauncher.launch(intent)
3Explicit Intent
An explicit intent specifies exactly which component (activity, service, receiver) to start by name. Use it when you know the target class.
Create SecondActivity: Right-click com.example.myfirstapp → New → Activity → Empty Views Activity. Name: SecondActivity. Android Studio adds it to the manifest automatically.
2
Add button in activity_main.xml with id goToSecondButton.
3
Implement click in MainActivity.kt (see code below).
XML — activity_main.xml<Button
android:id="@+id/goToSecondButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Go to Second Activity" />
Kotlin — Send and receive extras// Sending (MainActivity)
val intent = Intent(this, SecondActivity::class.java).apply {
putExtra("USER_NAME", "Alice")
putExtra("USER_AGE", 25)
putExtra("IS_PREMIUM", true)
}
startActivity(intent)
// Receiving (SecondActivity)
val userName = intent.getStringExtra("USER_NAME") ?: "Guest"
val userAge = intent.getIntExtra("USER_AGE", 0)
val isPremium = intent.getBooleanExtra("IS_PREMIUM", false)
textView.text = "Hello $userName, Age: $userAge, Premium: $isPremium"
Passing Serializable / Parcelable Objects
Kotlin — Parcelable User object// Data class (use @Parcelable for better performance)
@Parcelize
data class User(val name: String, val age: Int) : Parcelable
// Sending
val user = User("Bob", 30)
intent.putExtra("USER_OBJ", user)
// Receiving
val user = if (Build.VERSION.SDK_INT >= 33) {
intent.getParcelableExtra("USER_OBJ", User::class.java)
} else {
@Suppress("DEPRECATION")
intent.getParcelableExtra("USER_OBJ")
}
4Implicit Intent
An implicit intent doesn't specify the component name. Instead, it declares an action and optionally a data URI. Android finds the best app that can handle that action (browser, camera, dialer, share sheet).
Kotlinval shareIntent = Intent(Intent.ACTION_SEND).apply {
type = "text/plain"
putExtra(Intent.EXTRA_TEXT, "Check out this amazing app!")
putExtra(Intent.EXTRA_SUBJECT, "Sharing something cool")
}
startActivity(Intent.createChooser(shareIntent, "Share via"))
Example 4: Open a Location in Google Maps
Kotlinval gmmIntent = Intent(Intent.ACTION_VIEW, Uri.parse("geo:0,0?q=Times Square, New York"))
startActivity(gmmIntent)
Example 5: Capture a Photo (Implicit + Result)
Kotlinprivate lateinit var photoUri: Uri
private val takePictureLauncher = registerForActivityResult(
ActivityResultContracts.TakePicture()
) { success ->
if (success) {
imageView.setImageURI(photoUri)
}
}
fun capturePhoto() {
val photoFile = File(getExternalFilesDir(null), "photo.jpg")
photoUri = FileProvider.getUriForFile(
this,
"${packageName}.fileprovider",
photoFile
)
takePictureLauncher.launch(photoUri)
}
What if no app can handle the implicit intent?
Calling startActivity() with an intent that has no matching app causes a crash. Always check:
Kotlin — Safe implicit intent launchval intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://google.com"))
if (intent.resolveActivity(packageManager) != null) {
startActivity(intent)
} else {
Toast.makeText(this, "No app can handle this", Toast.LENGTH_SHORT).show()
}
5Passing Data Between Activities (Advanced)
Method 1: Using putExtra() (simple types)
Covered in Explicit Intent section — works for primitives and Strings.
Method 2: Using Bundles (organized data)
Kotlin — Bundle extras// Sender
val bundle = Bundle().apply {
putString("name", "Charlie")
putInt("score", 100)
putStringArray("tags", arrayOf("gamer", "coder"))
}
val intent = Intent(this, SecondActivity::class.java).putExtras(bundle)
startActivity(intent)
// Receiver
val bundle = intent.extras ?: Bundle()
val name = bundle.getString("name")
Method 3: Passing data BACK to previous activity
MainActivity (caller):
Kotlin — MainActivity callerprivate val getResultLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == RESULT_OK) {
val returnedText = result.data?.getStringExtra("result_data") ?: ""
textViewResult.text = returnedText
}
}
fun openSecondForResult() {
val intent = Intent(this, SecondActivity::class.java)
getResultLauncher.launch(intent)
}
SecondActivity (callee):
Kotlin — SecondActivity calleefun sendResultBack() {
val resultIntent = Intent().apply {
putExtra("result_data", "Hello from Second Activity!")
}
setResult(RESULT_OK, resultIntent)
finish() // Closes activity and returns to MainActivity
}
Method 4: Using ViewModel (shared across activities — advanced)
For complex data sharing, use a shared ViewModel scoped to the application or use SharedPreferences/database.
6Intent Filters
An intent filter (declared in the manifest) tells Android what implicit intents an activity can handle. Without intent filters, an activity can only be started via explicit intent.
Manifest Example: Making an Activity Handle "VIEW" Actions
Getting data from the intent that started your activity
Kotlin — MyWebViewerActivityclass MyWebViewerActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_web_viewer)
val action = intent.action
val data = intent.data // URI that triggered this
if (Intent.ACTION_VIEW == action && data != null) {
webView.loadUrl(data.toString())
}
}
}
Comparison: Explicit vs Implicit Intents
Aspect
Explicit Intent
Implicit Intent
Target
Specific class name
Any app that can handle action
Use case
Navigating within your app
Using external apps (browser, camera, share)
Requires
Class reference
Action and data
Manifest declaration
Always required
Not required for calling; required for receiving
Example
Intent(this, Settings::class.java)
Intent(ACTION_VIEW, webUri)
Who handles it
Exactly your component
System resolves best match
7Hands-On Exercises
1
Create a two-activity app where MainActivity has an EditText and a button. Clicking the button sends the text to SecondActivity and displays it there.
2
Use an implicit intent to open a specific location in Google Maps (e.g., Eiffel Tower).
3
Implement data return: In SecondActivity, add a button that sends a message back to MainActivity and displays it in a TextView.
4
Create a share button that shares a text message (e.g., "I love learning Android!") using ACTION_SEND.
5
Add an intent filter to one of your activities so it can be opened via a custom scheme myapp://start.
6
Experiment with lifecycle: Add Log statements to all lifecycle methods, then rotate the screen, press Home, open another app, and return. Observe the sequence in Logcat.
8Common Errors & Solutions
Error
Cause
Fix
ActivityNotFoundException
Activity not declared in manifest
Add <activity> tag for explicit; check action for implicit
NullPointerException on intent.getStringExtra()
Extra key doesn't exist
Use default values: intent.getStringExtra("key") ?: ""