Приложение закрывается сразу после нажатия кнопки Run в Android Studio почти всегда из-за необработанного исключения в потоке main — и первым делом нужно открыть вкладку Logcat и найти строку, начинающуюся с FATAL EXCEPTION: main. Именно в стектрейсе под ней указаны класс исключения, файл и номер строки, где произошёл сбой. Без этой информации любые попытки исправить вылет превращаются в гадание.
Проблема встречается как на эмуляторе, так и на реальном устройстве, и причины могут лежать в разных слоях: от опечатки в коде активности до конфликта версий библиотек или нехватки памяти виртуального устройства. Ниже разберём системный порядок диагностики — от чтения логов до проверки манифеста и зависимостей.
Читаем Logcat: главный источник информации
Откройте панель Logcat в нижней части окна Android Studio и выберите в фильтре своё устройство и пакет приложения. Установите уровень логирования Error, чтобы отсечь информационный шум. Затем запустите приложение повторно и дождитесь вылета.
Ищите блок, начинающийся со строки FATAL EXCEPTION: main. Сразу под ней будет тип исключения — например, java.lang.NullPointerException или android.content.ActivityNotFoundException — и цепочка вызовов at com.example.myapp.MainActivity.onCreate(MainActivity.java:42). Клик по синей ссылке с именем файла перенесёт вас прямо к проблемной строке кода.
Если лог пустой или обрывается, убедитесь, что в Logcat выбрано правильное устройство и процесс. Иногда после вылета процесс исчезает из списка — тогда переключите фильтр на No Filters и повторите запуск.
Типичные исключения и их причины
Большинство вылетов при запуске сводится к ограниченному набору ошибок. Знание типа исключения сразу сужает область поиска.
| Исключение | Вероятная причина | Где искать |
|---|---|---|
NullPointerException | Обращение к неинициализированной переменной или findViewById вернул null | Метод onCreate, проверка ID в layout |
ClassNotFoundException / NoClassDefFoundError | Класс не попал в сборку, проблема с зависимостями или ProGuard/R8 | build.gradle, правила обфускации |
ActivityNotFoundException | Активность не объявлена в манифесте или ошибка в имени пакета | AndroidManifest.xml |
Resources.NotFoundException | Ссылка на несуществующий ресурс: строку, цвет, layout | Папка res, имена ресурсов |
OutOfMemoryError | Загрузка слишком больших изображений или утечка памяти | Декодирование Bitmap, размеры drawable |
Обратите внимание: самая частая причина вылета «на пустом месте» — это findViewById с ID, которого нет в текущем layout-файле. Такое случается после переименования view или когда активность загружает не тот макет через setContentView.
Проверка кода активности и метода onCreate
Если стектрейс указывает на onCreate, внимательно пройдите по этому методу сверху вниз. Порядок вызовов имеет значение: setContentView() должен идти до любых обращений к элементам интерфейса. Обращение к findViewById до установки макета гарантированно вернёт null.
Для проектов на Kotlin проверьте переменные, объявленные как lateinit: обращение к ним до инициализации вызывает UninitializedPropertyAccessException. Также подозрительны вызовы сети или длительные операции в главном потоке — они могут завершаться ошибкой NetworkOnMainThreadException.
☑️ Проверка кода активности
Полезный приём — поставить точку останова на первой строке onCreate и запустить приложение через Debug (иконка жука) вместо обычного Run. Пошаговое выполнение покажет, на какой именно строке происходит сбой, и позволит посмотреть значения переменных в момент ошибки.
Манифест и ресурсы
Файл AndroidManifest.xml — вторая по частоте причина вылетов при старте. Каждая активность, которую вы запускаете через Intent, должна быть объявлена в манифесте внутри тега application. Проверьте, что имя класса указано корректно, включая пакет, если он отличается от корневого.
Также проверьте ссылки на тему приложения: если в атрибуте android:theme указан стиль, которого нет в res/values/themes.xml, приложение упадёт при создании активности. Аналогично ведут себя ссылки на несуществующие строки, цвета и иконки.
- 📋 Все запускаемые активности объявлены в
AndroidManifest.xml - 🎨 Тема из манифеста существует в файлах стилей
- 🖼️ Все ресурсы, на которые ссылается код, присутствуют в
res - 📦 Имена пакетов в манифесте и в
build.gradleсогласованы
⚠️ Внимание: после переименования или перемещения активности в другой пакет манифест не обновляется автоматически во всех случаях. Если вылет начался после рефакторинга — проверьте манифест первым делом.
Зависимости, Gradle и кэш сборки
Когда код и манифест в порядке, а приложение всё равно падает, источником может быть сборка. Конфликт версий библиотек в build.gradle иногда приводит к тому, что на устройство попадает не тот класс, который ожидает код. Проверьте секцию dependencies на дубли и смешение несовместимых версий одной библиотеки.
Если ошибка появилась «сама по себе» после обновления зависимостей, попробуйте очистить проект: меню Build → Clean Project, затем Build → Rebuild Project. В более запущенных случаях помогает File → Invalidate Caches / Restart — это сбрасывает кэш индексации среды.
./gradlew clean
./gradlew assembleDebug
Сборка из командной строки полезна тем, что показывает полный вывод Gradle без фильтрации IDE — иногда там видны предупреждения о конфликтах версий, которые Android Studio не отображает явно.
Проблемы эмулятора и устройства
Иногда виноват не код, а среда запуска. Эмулятор с малым объёмом выделенной памяти или устаревшим системным образом может завершать приложения, которые на реальном устройстве работают нормально. Проверьте параметры виртуального устройства в Device Manager: объём RAM, версию Android и тип образа.
На физическом устройстве проверьте, достаточно ли свободной памяти и не установлена ли старая версия приложения, собранная с другой конфигурацией. Полное удаление приложения с устройства перед повторной установкой исключает конфликты данных и подписи.
- 🔄 Пересоздайте эмулятор через
Device Manager → Wipe Dataили удалите и создайте заново - 📱 Удалите приложение с устройства и установите сборку заново
- 🧪 Проверьте запуск на другом устройстве или другой версии Android
- 💾 Убедитесь, что на устройстве есть свободное место
⚠️ Внимание: если приложение падает только на release-сборке, а в debug работает, почти наверняка дело в правилах R8/ProGuard, которые удаляют или переименовывают нужные классы. Проверяйте файлproguard-rules.proи добавляйте правила-keepдля классов, используемых через reflection.
Как проверить, виноват ли ProGuard/R8
Временно отключите минификацию, установив minifyEnabled false в блоке release файла build.gradle, и соберите release-сборку заново. Если приложение перестало вылетать — причина в правилах обфускации. Найдите в Logcat имя отсутствующего класса и добавьте для него правило -keep в proguard-rules.pro, затем верните minifyEnabled true.
Если ничего не помогло: системный подход
Когда стандартные шаги не дают результата, сузьте проблему методом исключения. Создайте новый пустой проект через мастер Android Studio и запустите его на том же устройстве. Если шаблонное приложение тоже вылетает — проблема в среде: эмуляторе, SDK или самой IDE, а не в вашем коде.
Другой приём — закомментировать содержимое onCreate и возвращать код частями, запуская приложение после каждого шага. Так вы локализуете блок, вызывающий сбой, даже если стектрейс неочевиден. Для фоновых компонентов — Service, BroadcastReceiver, инициализация в классе Application — добавьте логирование через Log.d() в начале каждого этапа.
Не игнорируйте предупреждения компилятора и подсветку анализатора кода: Android Studio часто помечает потенциальные NullPointerException и несовпадения ресурсов жёлтым ещё до запуска. Прогон Analyze → Inspect Code выдаёт список потенциальных проблем по всему проекту.
Частые вопросы
Почему приложение вылетает без видимой ошибки в Logcat?
Скорее всего, в Logcat выбран не тот процесс или стоит фильтр по уровню. Переключите фильтр на No Filters, выберите устройство и повторите запуск. Также проверьте, что приложение не вылетает в фоновом потоке — тогда исключение может обрабатываться библиотекой и не доходить до уровня Error.
Приложение падает только на реальном устройстве, на эмуляторе работает. Что делать?
Проверьте разрешения: на реальном устройстве опасные разрешения запрашиваются в рантайме, и их отсутствие может вызывать SecurityException. Также сравните версии Android и архитектуру процессора — нативные библиотеки могут отсутствовать для конкретной архитектуры устройства.
Вылетает сразу после обновления зависимостей в build.gradle. В чём причина?
Вероятен конфликт версий транзитивных зависимостей. Выполните ./gradlew app:dependencies, чтобы увидеть дерево зависимостей и найти дублирующиеся библиотеки с разными версиями. Зафиксируйте нужную версию явно или используйте блок constraints.
Можно ли отловить вылет, если он происходит до открытия Logcat?
Да. Подключите устройство и выполните в терминале команду adb logcat до запуска приложения — вывод пойдёт непрерывно, и вы не пропустите момент падения. Лог можно перенаправить в файл для последующего анализа.
Debug-сборка работает, а release падает. Где искать проблему?
Почти всегда причина в минификации и обфускации R8/ProGuard. Проверьте proguard-rules.pro, добавьте правила -keep для классов, используемых через reflection или сериализацию, и посмотрите стектрейс release-сборки — имена классов там будут обфусцированы, но маппинг в папке build/outputs/mapping позволяет восстановить исходные имена.