Question

Debug Android App Crashes with Logcat and Stack Traces

javaandroiddebuggingkotlin

Question

I am developing an Android application. Every time I run it, Android displays this message:

Unfortunately, MyApp has stopped.

How can I find the cause of the crash, fix it, or provide the information needed to ask an effective debugging question?

Short Answer

An Android “has stopped” dialog means that your app encountered an unhandled error and its process was terminated. You will learn how to use Logcat to locate the exception, read the important lines of a stack trace, identify the code that failed, and share useful crash details when asking for help.

Concept

Android shows a crash dialog when code throws an exception that is not handled. An exception is an error event, such as trying to use a missing view, reading beyond an array’s bounds, or using data that is null.

The dialog itself does not contain enough information to fix the problem. The useful diagnostic information is written to Logcat, Android Studio’s log viewer. A typical crash report contains:

  • An exception type, such as NullPointerException or IllegalArgumentException.
  • An explanatory message, when one is available.
  • A stack trace: a list of method calls that led to the failure.
  • A source file and line number, such as MainActivity.java:42.

The exception type explains what kind of failure occurred. The first stack-trace location belonging to your package usually shows where it occurred. Together, these clues turn “the app stopped” into a specific bug you can investigate.

This workflow matters in real programming because crashes are symptoms, not diagnoses. Rather than guessing at fixes, developers reproduce the problem, inspect the exception and source line, determine why the invalid state occurred, and fix the underlying cause.

Mental Model

Think of your app as a recipe being followed in a kitchen. The crash dialog says only, “The recipe could not be completed.” Logcat is the incident report: it says which instruction failed, why it failed, and which earlier instructions led to it.

A stack trace is like a trail of footprints. The top of the trail is where the failure was detected; lower entries show the calls that brought execution there. Your goal is usually to find the first footprint that belongs to your own code and inspect that line.

Take Quiz

Syntax and Examples

In Android Studio, open View > Tool Windows > Logcat, run the app again, and reproduce the crash. Filter the output by your application process or package name, then look for a crash entry containing FATAL EXCEPTION.

A simplified Java crash report might look like this:

FATAL EXCEPTION: main
Process: com.example.myapp, PID: 12345
java.lang.NullPointerException: Attempt to invoke virtual method
    'void android.widget.TextView.setText(...)' on a null object reference
    at com.example.myapp.MainActivity.onCreate(MainActivity.java:24)
    at android.app.Activity.performCreate(Activity.java:...)

The key part is:

at com.example.myapp.MainActivity.onCreate(MainActivity.java:24)

Open MainActivity.java and inspect line 24. For example, this code can cause that exception:

TextView title = findViewById(R.id.title);
title.setText("Welcome");

If title is null, the view was not found in the layout currently loaded by the activity. Common causes include:

  • The layout does not contain a view with @+id/title.
  • The wrong layout was passed to setContentView().
  • findViewById() ran before setContentView().

A corrected activity loads its layout before looking up views:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    TextView title = findViewById(R.id.title);
    title.setText("Welcome");
}

Step by Step Execution

Consider this activity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    TextView greeting = findViewById(R.id.greeting);
    greeting.setText("Hello");
}

Suppose activity_main.xml does not contain a view with the ID greeting.

  1. onCreate() starts when Android creates the activity.
  2. setContentView(R.layout.activity_main) loads the screen layout.
  3. findViewById(R.id.greeting) searches that loaded layout.
  4. No matching view exists, so greeting receives null.
  5. greeting.setText("Hello") tries to call setText on null.
  6. Java throws a NullPointerException.
  7. Because the exception is not handled, Android logs a stack trace and closes the app.
  8. Logcat points to the greeting.setText line in your activity.

Do not stop at adding a null check. The real fix is normally to make the layout and the code agree:

<TextView
    android:id="@+id/greeting"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

Real World Use Cases

Crash-reading skills apply throughout Android development:

  • Screen setup: A view ID is missing, a fragment uses the wrong layout, or a view is accessed too early.
  • User input: Text is converted to a number even though the field is empty or contains invalid characters.
  • Network data: An API response omits a field that the app assumed would always exist.
  • Lists and collections: Code accesses an item at an index that does not exist.
  • Permissions and platform features: The app accesses a camera, file, or location without the required permission or valid state.
  • Database work: A query returns no record, but code assumes a result is available.

In each case, Logcat identifies the exception and the source location, while the surrounding code explains the invalid assumption that must be fixed.

Take Quiz

Real Codebase Usage

Developers make crashes easier to diagnose by validating assumptions at boundaries and producing useful logs.

Validate external or optional data

String username = intent.getStringExtra("username");
if (username == null || username.trim().isEmpty()) {
    Log.w("ProfileActivity", "Missing username extra");
    finish();
    return;
}

This is a guard clause: it handles an invalid state early so the rest of the method can rely on a valid username.

Handle expected parsing failures

try {
    int quantity = Integer.parseInt(quantityInput.getText().toString());
    addToCart(quantity);
} catch (NumberFormatException exception) {
    quantityInput.setError("Enter a whole number");
}

Use try/catch for failures that are genuinely expected and recoverable. Do not wrap an entire activity in catch (Exception) just to hide crashes; that makes defects harder to find.

Log useful context

Log.d("Checkout", "Submitting order for cart item count: " + cartItems.size());

Logs should help answer what the app was doing. Never log passwords, tokens, payment details, or other sensitive personal data.

In production projects, teams also use crash-reporting tools to collect exception reports from real devices. The investigation process is still the same: read the exception, locate the app frame, reproduce when possible, and correct the root cause.

Common Mistakes

Trying to fix the dialog instead of the exception

The dialog is only a symptom. Changing the app name, reinstalling repeatedly, or adding random try/catch blocks does not identify the cause. Reproduce the crash and read Logcat.

Posting only “My app has stopped”

A crash message without a stack trace does not tell anyone which code failed. When requesting help, include:

  • The complete exception and stack trace from Logcat.
  • The relevant code around the line named in the stack trace.
  • The action that reproduces the crash.
  • Relevant XML layout, manifest, or input data when applicable.

Remove secrets such as API keys, tokens, and user data first.

Looking only at the last Logcat line

Logcat contains messages from Android and other processes. Find FATAL EXCEPTION, then read the exception message and the first line that references your package, for example com.example.myapp.

Catching every exception and ignoring it

Broken approach:

try {
    title.setText("Welcome");
} catch (Exception ignored) {
}

This prevents a visible crash but leaves the app in an unknown state and hides the real defect. Fix why title is invalid instead.

Adding a null check without deciding what null means

if (title != null) {
    title.setText("Welcome");
}

This may be appropriate if the view is truly optional. If the screen requires the title, the correct fix is to load the correct layout or use the correct ID.

Assuming the top Android framework frame is your bug

Framework lines explain that Android called your activity, but the most actionable line is often the first stack frame in your own package and source file.

Comparisons

ItemWhat it tells youHow to use it
Crash dialogThe app terminatedOpen Logcat; it does not identify the source line.
Exception typeThe category of failureFor example, NullPointerException means an object reference was null.
Exception messageDetails about the failed operationRead it before changing code.
Stack traceThe call path to the failureFind the first frame in your package.
Source line numberA likely location of the failing operationInspect that line and the values/state that reach it.
try/catchRecovery from expected failuresUse for recoverable cases, not to suppress programming mistakes.
ExceptionTypical meaningFirst thing to check
NullPointerExceptionA reference is nullView lookup, intent extra, API field, or object initialization.
NumberFormatExceptionText is not a valid requested numberUser input and parsing validation.
IndexOutOfBoundsExceptionA list/array index is invalidCollection size and loop bounds.
IllegalArgumentExceptionA method received an invalid valueMethod requirements and input values.
Resources.NotFoundExceptionA requested resource cannot be loadedResource ID, resource type, and configuration.
Take Quiz

Cheat Sheet

  • A stopped-app dialog usually means an unhandled exception.

  • Reproduce the crash while Logcat is open.

  • Search or filter for FATAL EXCEPTION.

  • Read the exception type and message.

  • Find the first stack frame in your package, such as:

    at com.example.myapp.MainActivity.onCreate(MainActivity.java:24)
    
  • Open that file and line, then inspect the assumptions on that line.

  • Fix the root cause, not merely the visible symptom.

  • Use guard clauses and validation for absent or invalid external input.

  • Catch only exceptions you can handle meaningfully.

  • When asking for help, provide the stack trace, relevant code, reproduction steps, and relevant XML/data.

  • Do not share secrets, tokens, passwords, or private user information in logs.

FAQ

Why does Android say “Unfortunately, app has stopped”?

It means the app process encountered an unhandled exception and Android terminated it. Logcat contains the reason.

Where can I find the Android crash stack trace?

In Android Studio, open View > Tool Windows > Logcat, run the app, and reproduce the problem. Look for FATAL EXCEPTION and your app’s process.

Which line of a stack trace should I fix first?

Start with the first line that names your application package, source file, and line number. Then read the exception message and inspect the surrounding code.

Does a NullPointerException always mean I should add a null check?

No. First determine why the reference is null. A null check is appropriate only when absence is valid and you have a useful fallback; otherwise fix the initialization, ID, layout, or data contract.

Should I use try/catch to stop my Android app from crashing?

Use it for expected, recoverable conditions, such as invalid numeric input. Do not use it to silently hide all exceptions; that masks defects and can leave incorrect behavior.

What should I include in an Android crash help request?

Include the complete exception and relevant stack trace, code around the referenced line, steps to reproduce the crash, and relevant layout XML or data. Remove sensitive information.

Why does the stack trace include Android classes I did not write?

Android calls your activity, fragment, or callback through framework code. Those entries show the call path; the frame in your package is usually the best starting point.

Take Quiz

Mini Project

Description

Build a small order-quantity screen that safely converts user input into a number. It demonstrates a common crash source—invalid numeric text—and replaces an unhandled exception with clear validation feedback.

Goal

Create an Android activity that accepts a quantity and displays a confirmation only for valid positive whole numbers.

Requirements

Use an EditText for the quantity and a Button to submit it. Reject empty input with an error message. Reject text that is not a whole number. Reject zero and negative quantities. Display a confirmation message for a valid positive quantity.

Take Quiz

Keep learning

Related questions

View more