Как снять логи для iOS и Android приложений
Мобильное приложение или приложение — это программное обеспечение, предназначенное для работы на смартфонах, планшетах и других мобильных устройствах.
Загружаются из магазина приложений (Google Play или App Store) на мобильном устройстве.
Виды мобильных приложений:
- Нативные
- Веб-приложения
- Гибридные
Распространенные причины возникновения багов в мобильных приложениях:
- Проблемы при установке/удалении мобильных приложений
- Проблемы с поддержкой различных версий ОС и устройств
- Проблемы с соблюдением принципов безопасности
- Проблемы с большим потреблением ресурсов девайса
- Проблемы со скоростью запуска и работы приложения
- Проблемы локализации
- Проблемы при вращении экрана
- Проблемы с непонятными пользователям сообщениями об ошибке
- Проблемы при подключении к интернету
- Проблемы, связанные с условиями работы офлайн
- Проблемы, связанные с низким уровнем заряда батареи
- Проблемы после перезагрузки телефона
- Проблемы после входящих звонков и SMS
Важную роль при диагностировании ошибок в мобильных приложениях играют логи.
Логи и их виды
Логи — это записи или сообщения в виде текста, в которых записываются все действия пользователя или ответы системы на действия пользователя, то есть, вся информация о том, что пользователь делает и что нажимает на самом устройстве в приложении.
Логи предназначены для того, чтобы более подробно воспроизвести ошибку, разобраться, в чем именно состоит проблема, и легче найти пути ее решения.
Виды логов
Логи мобильных приложений делятся на два основных вида: консольные (обычные) логи и креш-логи.
Консольные логи — это лог-файлы, являющиеся журналом событий и содержащие все записи о системных событиях, ответы устройства на действия пользователя, которые обновляются в режиме реального времени.
Креш-логи — это лог-файлы, которые создаются после экстренного завершения работы программы (креша). Файлы креш-логов имеют расширение .crash или .ips. Креш-логи содержат информацию с момента запуска программы и до экстренного завершения программы.
Как снять логи мобильных приложений
Существуют разные варианты снятия логов для мобильных приложений в зависимости от операционной системы телефона (Android, iOS).
Как снять логи с iOS
Одним из самых распространенных способов для получения логов для приложений iOS является получение с помощью XCode.
XCode — это среда разработки программного обеспечения для платформ macOS и iOS.
Для снятия логов через XCode необходимо:
- Установить XCode
- Подключите устройство к Mac
- Запустить XCode
- Открыть вкладку «Window» — «Devices and Simulators»
- Нажать кнопку «View Device Logs»
- Найти нужный лог-файл и скопировать его в текстовый файл
Также получить логи можно с помощью iMazing (доступно как для Windows, так и для MacOS).
Как снять логи с Андроид
Для того, чтобы снять с Android логи приложения, понадобится Android Studio.
Android Studio — интегрированная среда разработки (IDE) для платформы Android.
Для снятия логов с помощью Android Studio нужно:
- Установить Android Studio
- Создать новый проект в «Android Studio» (при создании нового проекта нужно правильно указать версию Android девайса, с которого необходимо снять логи)
- Включить режим разработчика на Android девайсе
- Подключить устройство через USB к компьютеру
- Выбрать девайс в Android Studio
- Выберите вкладку LogCat
- Воспроизвести ошибку на девайсе или найти по дате воспроизведения логи (если мы знаем время, когда воспроизводилась проблема)
- Выделить нужные логи и скопировать их (правой клавишей мыши → Copy или Ctrl+C)
- Создать файл .txt, добавить в него логи и сохранить их
Также для снятия логов с Android девайсов можно использовать Minimal ADB приложение.
- XCode — https://developer.apple.com/xc.
- Android Studio — https://developer.android.com/.
- iMazing — https://imazing.com/download
Как снять логи при краше мобильного приложения?
Всем привет! Я Tech Lead QA в мобильной разработке. При тестировании приложений иногда сталкиваемся со сбоем приложения. И в таких ситуациях очень важно уметь собирать логи с устройства, чтобы максимально быстро пофиксить ошибки. В этой статье я хотел бы рассказать, как мы это делаем в Альфа-Банке.
Осторожно, в статье много картинок.
Как получить логи с Android?
Есть, как минимум, 3 способа, с помощью которых можно получить логи при краше приложения:
- По USB из Android Studio.
- По USB через утилиту adb.
- Через приложение Crash Log Viewer — Show App Cr.
Перед тем, как начать снимать логи одним из трех перечисленных способов, настраиваем и подключаем девайс по USB.
Подготовка девайса
№1. Включаем режим разработчика. У разных моделей и производителей этот режим включается по разному. Но тут нет ничего сложного, 5 минут погуглить, как включается этот режим у вашей модели и всё получится.
№2. Переходим в настройки и заходим в раздел «Для разработчика» и включаем «Отладку по USB».
№3. Подключаем девайс по USB к ПК и разрешаем отладку по USB.
Девайс готов, теперь можно снимать логи. Рассмотрим первый способ.
Android Studio
Есть два способа установить Android Studio на ПК.
- С официального сайта developer.android.
- Скачиваем и устанавливаем себе JetBrain Toolbox.
Я предпочитаю второй способ, потому как легко обновлять Android Studio и заодно можно установить другие продукты JetBrain.
№1. После установки Android Studio на ПК запускаем приложение, создаём любой проект и переходим в раздел «Logcat».
№2. Выбираем девайс, подключенный по USB, и уровень логирования error.
№2.1. Можно составить фильтр из нескольких условий. Например, уровень логирования и названия приложения, которое хотите отфильтровать. Тогда мы получим логи только по этим параметрам.
Готово. Чтобы получить логи краша приложения и передать их компетентным сотрудникам (или разобраться самому) этого достаточно. Если этого алгоритма недостаточно — есть другие способы фильтрации, описанные на официальном сайте Android Studio.
Перейдем ко второму способу.
Android Debug Bridge (adb)
Сначала идем на официальный сайт Android по ссылке и устанавливаем на ПК утилиту adb.
№1. Открываем консоль и ищем ID девайса.
№2. Получаем ID девайса, подключенного по USB.
List of devices attached
8HVKGMRKN78TMZYH device
8HVKGMRKN78TMZYH — ID моего девайса. У вас он будет другим, но состоящим из подобного набора символов.
№3. Запускаем сбор логов с устройства в файл, командой.
adb logcat -b crash > log_crash_am.log
Теперь на смартфоне можно повторить действия, которые приводят к сбою приложения.
Чтобы остановить сбор логов, достаточно в консоли нажать комбинацию CTRL+C. Готово.
И последний способ получить логи с Android — через приложение…
Crash Log Viewer — Show App Cr
С Google Play устанавливаем приложение на девайс.
№1. Запускаем приложение и выбираем Crash Log Viewer.
После чего должно открыться окно с двумя adb командами.
№2. Открываем терминал на ПК и последовательно выполняем 2 команды, которые были указаны в приложении.
adb shell pm grant com.arumcomm.crashlogviewer android.permission.PACKAGE_USAGE_STATS
adb shell pm grant com.arumcomm.crashlogviewer android.permission.READ_LOGS
№3. Отключаем девайс от ПК после выполнения команд.
Теперь мы готовы к сбору логов через Crash Log Viewer. При любом краше приложение будет автоматически их собирать.
Чтобы получить или отправить логи запускаем приложение, переходим в раздел «Crash Log Viewer». Там появится список приложений, у которых был краш.
Логи приПереходим в интересующее приложение и смотрим логи, когда приложение «крашнулось».
Логи можно скопировать или поделиться.
Мне нравится снимать логи краша приложения на Android при помощи приложения, потому что:
- девайс не нужно каждый раз подключать по USB к ПК;
- не нужно настраивать фильтрацию и потом искать нужные записи в логах.
Как получить логи с iOS?
- Непосредственно на самом девайсе.
- Через Xcode.
Начнем с девайса.
Снять логи непосредственно с девайса iOS
№1. Переходим на iOS в «Настройки» → «Конфиденциальность».
№2. Идем в раздел «Аналитика и улучшения».
№3. Открываем «Данные Аналитики».
И попадаем в список логов девайса.
№4. Чтобы отфильтровать логи интересующего приложения, вводим в строку поиска его название.
№5. Проваливаемся в запись и видим логи приложения.
Теперь вы знаете, где хранятся логи в iOS и после воспроизведения краша приложения сможете найти их и отправить своим коллегам.
Переходим ко второму способу.
Сбор из приложения XCode
Этот способ требует определённой подготовки.
Для начала устанавливаем XCode на Mac. Да, к сожалению iOS дружит только с себе подобными.
Из-за большого размера XCode может устанавливаться немного дольше, чем вы планировали, так что можно налить себе чаёк и посмотреть любимый сериальчик.
Итак, XCode установлен,, теперь можно приступать к сбору логов.
№1. Подключаем девайс к Mac по USB и запускаем XCode.
Если появился запрос «Доверять этому компьютеру?» жмём «Доверять».
№2. В XCode переходим «Window» → «Devices and Simulators».
№3. Нажимаем «Open Console».
Откроется окно, в котором будут отображаться логи iOS.
№4. Для начала вывода логов в консоль нажимаем «Начать».
После этого в консоль начнут «сыпаться» логи.
№5. Для сбора логов только при краше приложения выбираем тип логов «Ошибки и сбои».
№6. Нажимаем на строку поиска, затем на клавиатуре нажимаем стрелку вправо —> и вводим название приложения, чтобы получилось примерно такое.
И нажимаем Enter.
Подведение итогов
Надеюсь моя статья облегчит процесс сбора логов и сделает вашу работу хоть чуточку, но интересней и приятней. Спасибо за внимание и отличного вам настроения.
Как снимать логи с устройств на Android и iOS: разбираемся с инструментами
Краткая инструкция по чтению и разбору логов мобильных устройств на Android и iOS, а также необходимые инструменты для Windows и MacOS.
Статья подготовлена red_mad_robot и «Альфа-Банком» на основе доклада Senior QA red_mad_robot Ольги Никитиной «Инструменты для снятия логов с Android / iOS устройств. Чтение и разбор» на митапе «QАчественное общение» при поддержке red_mad_robot.
Уровни логирования и что они означают
Для начала разберёмся с логами. Это текстовые файлы, в которых записываются все действия пользователя. Например, какие кнопки он нажимает в приложении и как на это оно реагирует в ответ.
Записи в логах формируются в хронологическом порядке. Самая свежая — внизу.
Есть два вида логов:
- Crash logs — файл, в котором хранятся записи только об ошибках экстренного завершения программы — по-простому, когда приложение крашнулось.
- Logs — простые логи, или журнал событий. Это файл, в котором хранятся системные записи и ответы устройства на действие пользователя.
Логи на мобильных устройствах бывают нескольких уровней:
Они представлены по уровню важности — от самого высокого к самому низкому, — и каждый следующий уровень включает в себя предыдущий. Например, VERBOSE содержит в себе логи всех остальных.
Примечание: уровни более применимы к логам на Android, потому что именно там такое разделение встречается чаще.
Рассмотрим подробнее каждый уровень.
Error (ERROR)
На этом уровне информируются ошибки работы системы.
Записи этого уровня требуют быстрого вмешательства разработчика — на такие ошибки нужно реагировать максимально быстро.
Как пример, такая запись в логе:
“ SpannableStringBuilder: SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length ”
Это ошибка, в которой говорится, что строковый элемент span не может быть пустым.
“ [ZeroHung]zrhung_get_config: Get config failed for wp[0x0008] ] ”
Эта системная ошибка сообщает, что происходит утечка памяти при взаимодействии с каким-то элементом или приложением.
Warning (WARN)
На этом уровне отображаются записи, сообщающие о каком-то неожиданном поведении, требующем внимания, или о ситуации, которая незнакома системе.
Например, сообщение ниже — запись из тестового приложения:
“ [OMX.hisi.video.decoder.avc] setting nBufferCountActual to 16 failed: -2147483648 “
Мы пытаемся декодировать запись в какой-то формат, но его нет. Ошибка сообщает о неуспешной попытке настройки видеоплеера в нужном формате.
“ BroadcastQueue: Permission Denial: broadcasting Intent ”
Эта системная ошибка говорит о сбое в работе одного из виджетов на устройстве.
Info (INFO)
На этот уровень приходят записи информационного характера, например о работе системы.
Допустим, такое сообщение об уровне заряда батареи на устройстве:
“ APwBatteryMonitor: screen off start battery: 100 ”
А это сообщение говорит о том, что экран устройства был выключен:
Ещё в логи этого уровня входят запросы от клиента на сервер: хедеры, тело запросов, которые отправляет клиент, и ответы сервера.
okhttp.OkHttpClient: server: nginx/1.15.9
okhttp.OkHttpClient: date: Thu, 23 Sep 2021 19:41:17 GMT
okhttp.OkHttpClient: content-type: application/json
okhttp.OkHttpClient: vary: Accept-Encoding
okhttp.OkHttpClient: strict-transport-security: max-age=15724800; includeSubDomains
Такие записи могут помочь вам в понимании какого-то бага или в разборе задачи при условии, что вы не можете перехватить трафик или не знаете, какие запросы отправляются на бэкенд.
Debug (DEBUG)
Это уровень сообщений, в которых передаётся информация о процессах отладки или шагах работы крупных процессов.
Например, в записи ниже сказано, что пользователь нажимал на кнопку уменьшения или увеличения громкости:
Сначала мы видим запись о самом факте нажатия на кнопку, далее оно расшифровывается подробнее:
Ещё пример: если ваше приложение использует сокет-сессию, то на уровне DEBUG мы можем увидеть, когда сессия начинается и заканчивается:
“ b$b: WebSocket connected ”
Verbose (VERBOSE)
Сообщения такого уровня уточняют или раскрывают действия.
Например, у нас есть служба управления окнами на экране приложения. И на уровне Verbose мы можем увидеть подробности её работы.
WindowManager: Removing Window
На этом уровне мы можем посмотреть системные подробности наших действий. Например, при включении геолокации в записи отобразится текущая геолокация.
GnssLocationProvider: reportLocation Location [. ]
А меняя звук на устройстве, мы увидим, как растёт или падает значение:
AudioManager: getStreamVolume streamType: 3 volume: 10
Каждое нажатие, то есть изменение звука, будет отражаться новым сообщением.
Verbose — уровень самого низкого приоритета. Выбирая такой уровень отображения логов, мы будем видеть записи и со всех предыдущих уровней.
Примечание: разработчики приложения самостоятельно покрывают действия логами, определяют уровни, а также какие сообщения какому из них соответствуют.
Инструменты для снятия логов: Android
Расскажем о трёх способах.
Первый — Logcat в составе Android Studio, самый известный и широко используемый.
Для снятия логов нам необходимо перевести устройство в режим разработчика/отладки. Для этого нужно:
- найти в настройках номер нашего билда или ОС (в зависимости от устройства),
- около десяти раз нажать на эту информацию,
- при появлении сообщения о том, не хотим ли мы перевести устройство в режим разработчика, нажать «Ок».
Примечание: алгоритм может отличаться в зависимости от производителя устройства, потому что у многих из них свои надстройки на ОС Android.
Дальше подключаем устройство по USB к ПК и устанавливаем Android Studio.
Следующие шаги на скрине:
- Выбираем вкладку Logcat (переходим к сообщениям в реальном времени).
- В окошке выбираем телефон, с которого снимаем логи.
- На этой вкладке выбираем логи определённого приложения. Если нужно снять вообще все логи со всех приложений и системы, эту вкладку стоит не трогать. Рядом с ней можно выбрать уровень логирования (вкладка Verbose на скрине).
- В поле поиска, где мы можем фильтровать выдачу, разрешено писать что угодно — от названия пакета до частей вроде fatal.
На скрине видно логи с подключенного устройства.
Второй способ — выгрузка логов с самого устройства. Кроме режима разработчика нам нужно подключить устройство к ПК через USB и установить ADB — Android Debug Bridge.
Открываем терминал и пишем две команды.
Первая — adb devices — показывает подключённые устройства, которые видит ADB. В терминале выглядит так:
Вводим вторую команду — adb -s название устройства logcat, — которая запускает утилиту Logcat для конкретного устройства. В терминале в реальном времени будут поступать логи.
Как их читать?
- В первом столбце — дата и время поступления записи.
- Во втором — обозначения уровней логирования. Например, D — это Debug.
- В третьем показываются названия инструмента, утилиты, пакета, от которых поступает сообщение, а также расшифровка того, что вообще происходит.
Третий инструмент — SDK Platform Tools. Процесс его установки практически аналогичен предыдущим двум:
- переводим телефон в режим разработчика,
- подключаем к ПК по USB,
- скачиваем на ПК папку SDK PT (под свою ОС),
- открываем папку SDK PT в терминале.
Теперь пишем команду ./adb logcat –v threadtime > ./android-debug.log.
В терминале это выглядит так:
Прерываем выполнение команды (например, на Mac это Control+C). Лог добавляется в папку.
Очень похоже на предыдущий терминал, но файл обновляется, пока в терминале действует команда.
Инструменты снятия логов: iOS
В первую очередь нас интересует xCode — интегрированная среда разработки (IDE), в которую встроен нужный нам инструмент Simulator.
Как использовать инструмент:
- Устанавливаем xCode.
- В системной строке нажимаем xCode → Open Developer Tools → Simulator.
- Устанавливаем приложение.
- В самом симуляторе выбираем Debug → Open System Log.
Мы будем видеть логи в реальном времени:
Подобное оформление логов мы уже где-то видели, но построение информации в выдаче немного отличается. Есть дата и время (1) и данные (2) о том, с какого устройства снята информация: имя компьютера, элемент системы, с которого пришло сообщение, и его расшифровка.
Но первый способ работает только с симуляторами. Если необходимо снимать логи с реального устройства, в этом может помочь раздел Devices and Simulators.
Записи можно отфильтровать по конкретному процессу (вашему приложению):
- Устанавливаем xCode.
- Подключаем устройство к ПК по USB.
- Открываем xCode → Windows → Devices and Simulators.
Дальше нажимаем у устройства Open Console и видим панель с названием устройства, информацией о модели и ОС:
Логи поступают в реальном времени, но их удобно отслеживать:
У нас есть три столбца:
- «Время» — время поступления сообщения.
- «Процесс» — с какой части системы/приложения пришло сообщение.
- «Сообщение» — описание события, сервисная информация.
В инструменте есть поиск для фильтрации выдачи. Ещё есть полезная кнопка «Приостановить» — она останавливает поток логов.
А вот утилита iMazing поможет снимать iOS-логи для тех, у кого установлен Windows. Приложение платное, но часть функциональности доступна бесплатно. Например, за снятие логов устройства платить не нужно.
В меню выбираем «Показать консоль устройства». В открывшемся окне приходят записи логов в реальном времени со всего устройства.
Ещё одно важное достоинство iMazing — возможность сохранять логи (разумеется, по кнопке «Сохранить»).
Статья подготовлена red_mad_robot и «Альфа-Банком» на основе доклада Senior QA red_mad_robot Ольги Никитиной «Инструменты для снятия логов с Android / iOS устройств. Чтение и разбор» на митапе «QАчественное общение» при поддержке red_mad_robot.
Гайд по отладке Android-приложения: ищем баги и читаем логи
Иногда в приложении встречаются ошибки, которые нельзя увидеть даже после запуска. Например, код компилируется, проект запускается, но результат далёк от желаемого: приложение падает или вдруг появляется какая-то ошибка (баг). В таких случаях приходится «запасаться логами», «брать в руки отладчик» и искать ошибки.
Часто процесс поиска и исправления бага состоит из трёх шагов:
- Воспроизведение ошибки — вы понимаете, какие действия нужно сделать в приложении, чтобы повторить ошибку.
- Поиск места ошибки — определяете класс и метод, в котором ошибка происходит.
- Исправление ошибки.
Если приложение не падает и чтение логов ничего не даёт, то найти точное место ошибки в коде помогает дебаггер (отладчик) — инструмент среды разработки.
Чтобы посмотреть на логи и воспользоваться дебаггером, давайте напишем простое тестовое (и заведомо неправильное) приложение, которое даст нам все возможности для поиска ошибок.
Это будет приложение, которое сравнивает два числа. Если числа равны, то будет выводиться результат «Равно», и наоборот. Начнём с простых шагов:
- Открываем Android Studio.
- Создаём проект с шаблоном Empty Activity.
- Выбираем язык Java, так как его, как правило, знают больше людей, чем Kotlin.
Узнай, какие ИТ — профессии
входят в ТОП-30 с доходом
от 210 000 ₽/мес
Павел Симонов
Исполнительный директор Geekbrains
Команда GeekBrains совместно с международными специалистами по развитию карьеры подготовили материалы, которые помогут вам начать путь к профессии мечты.
Подборка содержит только самые востребованные и высокооплачиваемые специальности и направления в IT-сфере. 86% наших учеников с помощью данных материалов определились с карьерной целью на ближайшее будущее!
Скачивайте и используйте уже сегодня:
Павел Симонов
Исполнительный директор Geekbrains
Топ-30 самых востребованных и высокооплачиваемых профессий 2023
Поможет разобраться в актуальной ситуации на рынке труда
Подборка 50+ бесплатных нейросетей для упрощения работы и увеличения заработка
Только проверенные нейросети с доступом из России и свободным использованием
ТОП-100 площадок для поиска работы от GeekBrains
Список проверенных ресурсов реальных вакансий с доходом от 210 000 ₽
Получить подборку бесплатно
Уже скачали 27934
Нам автоматически откроются две вкладки: activity_main.xml и MainActivity.java. Сначала нарисуем макет: просто замените всё, что есть в activity_main.xml, на код ниже:
Можете запустить проект и посмотреть, что получилось:
Теперь оживим наше приложение. Скопируйте в MainActivity этот код:
public class MainActivity extends AppCompatActivity < @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final Button button = (Button) findViewById(R.id.button); final EditText first = (EditText) findViewById(R.id.first_number_et); final EditText second = (EditText) findViewById(R.id.second_number_et); final TextView answer = (TextView) findViewById(R.id.answer_tv); button.setOnClickListener(new View.OnClickListener() < @Override public void onClick(View v) < Integer firstInt = Integer.parseInt(first.getText().toString()); Integer secondInt = Integer.parseInt(second.getText().toString()); if (firstInt == secondInt) < answer.setText("Равно"); >else < answer.setText("Равно"); >> >); > >
В этом коде всё просто:
- Находим поля ввода, поле с текстом и кнопку.
- Вешаем на кнопку слушатель нажатий.
- По нажатию на кнопку получаем числа из полей ввода и сравниваем их.
- В зависимости от результата выводим «Равно» или «Не равно».
Для вас подарок! В свободном доступе до 05.05 —>
Скачайте ТОП-10
бесплатных нейросетей
для программирования
Помогут писать код быстрее на 25%
Чтобы получить подарок, заполните информацию в открывшемся окне
Запустим приложение и введём буквы вместо чисел:
Нажмём на кнопку, и приложение упадёт! Время читать логи. Открываем внизу слева вкладку «6: Logcat» и видим:
Читать логи просто: нужно найти красный текст и прочитать сообщение системы. В нашем случае это java.lang.NumberFormatException: For input string: «f». Указан тип ошибки NumberFormatException, который говорит, что возникла какая-то проблема с форматированием числа. И дополнение: For input string: «f». Введено “f”.
Уже можно догадаться, что программа ждёт число, а мы передаём ей символ. Далее в красном тексте видно и ссылку на проблемную строку: at com.example.appdebugging.MainActivity$1.onClick(MainActivity.java:26). Проблема в методе onClick класса MainActivity, строка 24. Можно просто кликнуть по ссылке и перейти на указанную строку:
int firstInt = Integer.parseInt(first.getText().toString());
Конечно, метод parseInt может принимать только числовые значения, но никак не буквенные! Даже в его описании это сказано — и мы можем увидеть, какой тип ошибки этот метод выбрасывает (NumberFormatException).
Здесь мы привели один из примеров. Типов ошибок может быть огромное количество, все мы рассматривать не будем. Но все ошибки в Logcat’е указываются по похожему принципу:
- красный текст;
- тип ошибки — в нашем случае это NumberFormatException;
- пояснение — у нас это For input string: «f»;
- ссылка на строку, на которой произошла ошибка — здесь видим MainActivity.java:26.
Исправим эту ошибку и обезопасим себя от некорректного ввода. Добавим в наши поля ввода android:inputType=»number», а остальной код оставим без изменений:
Теперь можем вводить только числа. Проверим, как работает равенство: введём одинаковые числа в оба поля. Всё в порядке:
На равенство проверили. Введём разные числа:
Тоже равно. То есть приложение работает, ничего не падает, но результат не совсем тот, который требуется. Наверняка вы и без дебаггинга догадались, в чём ошибка, потому что приложение очень простое, всего несколько строк кода. Но такие же проблемы возникают в приложениях и на миллион строк. Поэтому пройдём по уже известным нам этапам дебаггинга:
- Воспроизведём ошибку: да, ошибка воспроизводится стабильно с любыми двумя разными числами.
- Подумаем, где может быть ошибка: наверняка там, где сравниваются числа. Туда и будем смотреть.
- Исправим ошибку: сначала найдём её с помощью дебаггера, а когда поймём, в чём проблема, — будем исправлять.
Дарим скидку от 60%
на обучение «Android-разработчик» до 05 мая
Уже через 9 месяцев сможете устроиться на работу с доходом от 150 000 рублей
И здесь на помощь приходит отладчик. Для начала поставим точки останова сразу в трёх местах:
Чтобы поставить или снять точку останова, достаточно кликнуть левой кнопкой мыши справа от номера строки или поставить курсор на нужную строку, а затем нажать CTRL+F8. Почему мы хотим остановить программу именно там? Чтобы посмотреть, правильные ли числа сравниваются, а затем определить, в какую ветку в нашем ветвлении заходит программа дальше.
Запускаем программу с помощью сочетания клавиш SHIFT+F9 или нажимаем на кнопку с жучком:
Появится дополнительное окно, в котором нужно выбрать ваш девайс и приложение:
Вы в режиме дебага. Обратите внимание на две вещи:
- Точки останова теперь помечены галочками. Это значит, что вы находитесь на экране, где стоят эти точки, и что дебаггер готов к работе.
- Открылось окно дебага внизу: вкладка «5: Debug». В нём будет отображаться необходимая вам информация.
Введём неравные числа и нажмём кнопку «РАВНО?». Программа остановилась на первой точке:
- Сразу подсвечивается синим строка, где программа остановлена: в окне кода на 28-й строке и в левом окне отладчика (там даже можно увидеть, какой метод вызван, — onClick).
- В правом, основном окне отладчика, всё гораздо интереснее. Здесь можно увидеть инстансы наших вью (answer, first, second), в конце которых серым текстом даже отображаются их id. Но интереснее всего посмотреть на firstInt и secondInt. Там записаны значения, которые мы сейчас будем сравнивать.
Только до 2.05
Скачай подборку материалов, чтобы гарантированно найти работу в IT за 14 дней
Список документов:
ТОП-100 площадок для поиска работы от GeekBrains
20 профессий 2023 года, с доходом от 150 000 рублей
Чек-лист «Как успешно пройти собеседование»
Чтобы зарегистрироваться на бесплатный интенсив и получить в подарок подборку файлов от GeekBrains, заполните информацию в открывшемся окне
Как видим, значения именно такие, какие мы и ввели. Значит, проблема не в получении чисел из полей. Давайте двигаться дальше — нам нужно посмотреть, в правильную ли ветку мы заходим. Для этого можно нажать F8 (перейти на следующую строку выполнения кода). А если следующая точка останова далеко или в другом классе, можно нажать F9 — программа просто возобновит работу и остановится на следующей точке. В интерфейсе эти кнопки находятся здесь:
Остановить дебаггер, если он больше не нужен, можно через CTRL+F2 или кнопку «Стоп»:
В нашем случае неважно, какую кнопку нажимать (F9 или F8). Мы сразу переходим к следующей точке останова программы:
Ветка правильная, то есть логика программы верна, числа firstInt и secondInt не изменились. Зато мы сразу видим, что подпись некорректная! Вот в чём была ошибка. Исправим подпись и проверим программу ещё раз.
Мы уже починили два бага: падение приложения с помощью логов и некорректную логику (с помощью отладчика). Хеппи пас (happy path) пройден. То есть основная функциональность при корректных данных работает. Но нам надо проверить не только хеппи пас — пользователь может ввести что угодно. И программа может нормально работать в большинстве случаев, но вести себя странно в специфических состояниях. Давайте введём числа побольше и посмотрим, что будет:
Не сработало — программа хочет сказать, что 1000 не равна 1000, но это абсурд. Запускаем приложение в режиме отладки. Точка останова уже есть. Смотрим в отладчик:
Числа одинаковые, что могло пойти не так? Обращаем внимание на тип переменной — Integer. Так вот в чём проблема! Это не примитивный тип данных, а ссылочный. Ссылочные типы нельзя сравнивать через ==, потому что будут сравниваться ссылки объектов, а не они сами. Но для Integer в Java есть нюанс: Integer может кешироваться до 127, и если мы вводим по единице в оба поля числа до 127, то фактически сравниваем просто int. А если вводим больше, то получаем два разных объекта. Адреса у объектов не совпадают, а именно так Java сравнивает их.
Есть два решения проблемы:
- Изменить тип Integer на примитив int.
- Сравнивать как объекты.
Не рекомендуется менять тип этих полей в реальном приложении: числа могут приходить извне, и тип лучше оставлять прежним. Изменим то, как мы сравниваем числа:
if (firstInt.equals(secondInt)) < answer.setText("Равно"); >else
Всё работает. Наконец-то! Хотя… Давайте посмотрим, что будет, если пользователь ничего не введёт, но нажмёт на кнопку? Приложение опять упало… Смотрим в логи:
Опять NumberFormatException, при этом строка пустая. Давайте поставим точку останова на 26-й строке и заглянем с помощью отладчика глубже.
Нажмём F8 — и перейдём в глубины операционной системы:
Интересно! Давайте обернём код в try/catch и посмотрим ошибке в лицо. Если что, поправим приложение. Выделяем код внутри метода onClick() и нажимаем Ctrl+Alt+T:
Выбираем try / catch, среда разработки сама допишет код. Поставим точку останова. Получим:
Запускаем приложение и ловим ошибку:
Действительно, как и в логах, — NumberFormatException. Метод parseInt выбрасывает исключение, если в него передать пустую строку. Как обрабатывать такую проблему — решать исключительно вам. Два самых простых способа:
- Проверять получаемые строки first.getText().toString() и second.getText().toString() на пустые значения. И если хоть одно значение пустое — говорить об этом пользователю и не вызывать метод parseInt.
- Или использовать уже готовую конструкцию try / catch:
Теперь-то точно всё в порядке! Хотя профессиональным тестировщикам это приложение никто не отдавал: поищете ещё ошибки?