Table of Contents
Understanding Common Android Issues
When you build Android apps, you will repeatedly meet the same kinds of problems. Learning to recognize these patterns is as important as learning any API. This chapter focuses on how typical issues look at runtime, how to read their error messages, and what kinds of fixes usually work.
The goal is not to catalog every possible bug, but to help you develop a debugging mindset that you can reuse whenever something goes wrong.
Crashes and Stack Traces
A crash is when your app stops and the system shows a dialog that the app has stopped working. In Logcat, this usually appears as an exception with a stack trace. Reading this trace is the first and most important skill when dealing with problems.
The stack trace tells you which exception occurred and on which line of which file it happened. The most useful line is usually the first line that points into your own code, not the lines that refer to Android framework classes.
For example, you might see something like this in Logcat:
java.lang.NullPointerException: Attempt to invoke virtual method
'java.lang.String toString()' on a null object reference
at com.example.myapp.MainActivity.onCreate(MainActivity.kt:37)
at android.app.Activity.performCreate(Activity.java:...)
Here, the exception type is NullPointerException, and the key line is the one that mentions MainActivity.kt:37. This tells you where to start looking.
Always scroll to the top of the stack trace and find the first line that mentions your package name. Start debugging from that line.
If the app closes without any visible error dialog, check Logcat filters. Make sure you are looking at your app process and not missing the exception because Logcat is filtered too strictly.
Dealing with NullPointerException
NullPointerException is one of the most common errors. It occurs when you try to use a reference that is null as if it were a valid object.
Typical causes include trying to access a view before setContentView is called, using a property that you forgot to initialize, or assuming that an incoming value from an Intent or a bundle will never be null.
In Kotlin, null safety helps, but it does not remove this error completely. You can still force nullability with the !! operator or interact with Java APIs that return null. When an exception mentions kotlin.KotlinNullPointerException or null cannot be cast to non-null type, it usually means you violated a Kotlin null contract.
To debug this, inspect the exact line the stack trace points to and check any variable that could be null. Then trace back where that variable is set. If the value comes from the outside world, such as an intent extra or a network response, do not assume it is non null without proper checks.
View Binding and Layout Related Errors
User interface code is a common source of bugs, because it depends on the current layout and activity or fragment state.
One frequent issue is asking for a view that does not exist in the currently set layout. For example, calling findViewById(R.id.buttonSubmit) in an activity that uses a layout which does not define buttonSubmit. The result often appears as a NullPointerException when you use the returned reference.
If you see a crash related to a specific view usage, verify that your activity or fragment is inflating the correct layout file, and that the view ID in the code matches the ID defined in the XML.
When you use view binding or data binding, initialization order matters. If you access a binding property before the binding is created or after it is cleared, you will also see null related crashes.
Pay attention to lifecycle methods. In fragments, views are created and destroyed as the user navigates. Referring to old view references after onDestroyView has been called leads to unexpected errors.
Resource Not Found and ID Mismatches
Android resources such as strings, colors, layouts, and drawables are accessed through generated IDs in the R class. If your app complains about missing resources, the cause is often an incorrect name, type, or import.
A typical runtime error looks like this:
android.content.res.Resources$NotFoundException: String resource ID #0x0This happens if you pass a plain integer where Android expects a string resource ID, or if you have deleted or renamed a resource incorrectly.
At compile time, you might see messages that R cannot be resolved, or R.id.someView does not exist. This often appears when there is an error in an XML resource file. Even a small typo in a layout or values XML can prevent the R class from being generated correctly.
To debug this, always check the "Problems" or "Build" pane, and open the XML file mentioned in the error. Fix the syntax error, missing closing tag, or wrong attribute. Clean builds sometimes help regenerate resources if the project gets into a strange state.
Also watch your imports. Importing the wrong R class, for example from a library package, leads to confusing ID mismatches. Make sure your code imports your own app package R, not another one.
Activity and Intent Related Issues
Navigation between screens depends on activities and intents. Several common problems appear here.
One frequent runtime error is:
android.content.ActivityNotFoundException: Unable to find explicit activity
class com.example.myapp.SecondActivity; have you declared this activity in your AndroidManifest.xml?
This means you attempted to start an activity that is not registered in AndroidManifest.xml. To fix this, ensure that every activity you want to start has an <activity> entry in the manifest file with the correct fully qualified class name.
Another typical issue comes from incorrectly passing or reading data between activities. If you attempt to read an extra from an intent with the wrong key or the wrong type, you will get unexpected nulls or cast exceptions at runtime.
To avoid this, keep keys as constants in one place, and make sure both the sending and receiving side use the same key and the same data type. Check the intent content in Logcat if something behaves unexpectedly. You can print intent.extras to see what is actually present.
List and RecyclerView Errors
Lists are central to many Android apps and they introduce their own set of common bugs.
A typical crash in a list appears as an IndexOutOfBoundsException. This happens when the adapter believes there are more items than the backing list actually contains, or vice versa. You might see a message similar to:
IndexOutOfBoundsException: Inconsistency detected. Invalid item position
This usually points to an issue in your adapter implementation, such as returning the wrong size in getItemCount, or modifying the underlying data without notifying the adapter properly. If you remove or add items in the list, make sure to call the appropriate notify methods on the adapter, or to submit a new list when you use specialized adapter helpers.
Click handling inside a RecyclerView can also cause NullPointerException if you rely on views or data that are not valid for a particular position. When debugging, carefully log the position and data of items before using them.
Background Work and Threading Problems
Concurrency problems are often less obvious. They might not crash the app immediately but cause freezes, slowdowns, or occasional unexpected behavior.
One common issue is doing long running work on the main thread. This can lead to an Application Not Responding dialog. While the specific implementation of coroutines and background mechanisms is covered elsewhere, as a beginner you should at least be aware that networking, heavy computation, and long file operations should not run on the main thread.
Another typical error is trying to update the UI from a background thread. If you see an exception that complains about "Only the original thread that created a view hierarchy can touch its views", it means you are changing views from a non main thread. In that case, move UI updates back to the main thread using the appropriate mechanisms introduced in background chapters.
Networking and JSON Related Errors
When you start working with networking, several recurring problems appear.
If you see NetworkOnMainThreadException, you are making a network call on the main thread. You must move that call to a background mechanism.
JSON parsing errors often appear as JSONException or an exception from your JSON library that mentions unexpected tokens or mismatched types. In many cases, the actual JSON response from the server does not match your data model. To debug this, print or log the raw JSON string before parsing and compare it to the structure of your data class or object.
HTTP error codes do not always crash the app, but they should be checked. If a request silently fails and you never check the status code, you might start seeing nulls later in your code when you assume data is present. Handle error codes and missing data early to avoid hidden crashes.
Typical Layout and UI Rendering Problems
Sometimes the app does not crash, but the UI does not look or behave as you expect. For example, a view might not appear at all, or touch events might not be registered.
A frequent cause is incorrect layout constraints or missing layout parameters. For instance, a ConstraintLayout child without any constraints might end up at position (0,0) with size zero. In this case, the debugger will not show an error, but the view will simply not be visible.
Also, overlapping views might intercept touches. If a transparent or off screen view is placed above another view, clicks might be eaten by the overlay. Use the layout inspector in Android Studio to see the actual view hierarchy and sizes when the app is running.
Text not appearing correctly can be traced back to incorrect text color or background color combinations, missing fonts, or very small sizes. Adjusting dimensions and colors in the resources and verifying in the preview and on a real device helps here.
Dealing with ClassCastException and Type Issues
ClassCastException happens when you cast an object to an incompatible type. In Android, this often appears when you cast a view to the wrong subclass, or when you read a bundle extra as the wrong type.
For example, if you write:
val button = findViewById<TextView>(R.id.myButton)
while myButton is actually a Button, you might see a runtime cast exception.
Similarly, if you put a String extra into an intent but try to read it as an Int, you will get a type related error.
When such an exception occurs, carefully compare the actual type with what you expect. Check the XML definition of views, and confirm the type of extras at the point where you put them into the bundle or intent.
Issues Caused by Configuration Changes
Configuration changes such as device rotation recreate activities and often fragments. If your app loses data or crashes after rotation, the cause is usually that some state was being stored only in the activity instance or in views without any persistence.
Another related problem is keeping references to old activities or views in objects that outlive them. This can lead to crashes, memory leaks, or unexpected behavior after a rotation. If a callback or listener tries to interact with a destroyed activity, exceptions may appear.
To debug configuration related issues, reproduce them while watching Logcat. Rotate the device or emulator and see how the lifecycle logs behave. Check which objects are recreated and which are not, and ensure that you do not store logic that must survive rotation in a place that is tied to a specific activity instance.
Using Logcat Effectively for Problem Diagnosis
For almost every issue described in this chapter, Logcat is your primary source of truth. Learning how to filter and search its output speeds up debugging.
Filter by your app process, by tag, or by log level to reduce noise. Add your own log statements to confirm assumptions about variable values, code paths, and timing. For example, log when a function is entered and log the data it receives. If your expectation does not match the logs, you have found a starting point for the fix.
Also, pay attention to warnings, not only errors. Some warnings, such as strict mode messages, deprecation notes, or resource usage hints, can point you to potential problems before they turn into crashes.
Never ignore the first error or exception in Logcat. Later messages may only be side effects. Fixing the root cause usually removes several symptoms at once.
Building a Debugging Mindset
Common issues repeat, but every app is slightly different. Rather than memorizing specific errors, practice a consistent approach.
First, reproduce the problem reliably. Second, inspect Logcat and identify the first relevant exception or warning. Third, locate the exact line in your code. Fourth, verify your assumptions with temporary logs or test values. Finally, apply a small, focused change and test again.
Over time, you will start to recognize patterns. NullPointerException in views suggests inflation or lifecycle problems. Resources$NotFoundException suggests a resource mismatch. ActivityNotFoundException suggests a manifest issue. Seeing these patterns early lets you fix bugs faster and with more confidence.