Silent logging что это за программа на андроид
Иногда в приложении встречаются ошибки, которые нельзя увидеть даже после запуска. Например, код компилируется, проект запускается, но результат далёк от желаемого: приложение падает или вдруг появляется какая-то ошибка (баг). В таких случаях приходится «запасаться логами», «брать в руки отладчик» и искать ошибки.
Часто процесс поиска и исправления бага состоит из трёх шагов:
- Воспроизведение ошибки — вы понимаете, какие действия нужно сделать в приложении, чтобы повторить ошибку.
- Поиск места ошибки — определяете класс и метод, в котором ошибка происходит.
- Исправление ошибки.
Если приложение не падает и чтение логов ничего не даёт, то найти точное место ошибки в коде помогает дебаггер (отладчик) — инструмент среды разработки.
Чтобы посмотреть на логи и воспользоваться дебаггером, давайте напишем простое тестовое (и заведомо неправильное) приложение, которое даст нам все возможности для поиска ошибок.
Это будет приложение, которое сравнивает два числа. Если числа равны, то будет выводиться результат «Равно», и наоборот. Начнём с простых шагов:
- Открываем Android Studio.
- Создаём проект с шаблоном Empty Activity.
- Выбираем язык Java, так как его, как правило, знают больше людей, чем Kotlin.
Нам автоматически откроются две вкладки: activity_main.xml и MainActivity.java. Сначала нарисуем макет: просто замените всё, что есть в activity_main.xml, на код ниже:
Можете запустить проект и посмотреть, что получилось:
Теперь оживим наше приложение. Скопируйте в MainActivity этот код:
В этом коде всё просто:
- Находим поля ввода, поле с текстом и кнопку.
- Вешаем на кнопку слушатель нажатий.
- По нажатию на кнопку получаем числа из полей ввода и сравниваем их.
- В зависимости от результата выводим «Равно» или «Не равно».
Запустим приложение и введём буквы вместо чисел:
Нажмём на кнопку, и приложение упадёт! Время читать логи. Открываем внизу слева вкладку «6: Logcat» и видим:
Конечно, метод parseInt может принимать только числовые значения, но никак не буквенные! Даже в его описании это сказано — и мы можем увидеть, какой тип ошибки этот метод выбрасывает (NumberFormatException).
Здесь мы привели один из примеров. Типов ошибок может быть огромное количество, все мы рассматривать не будем. Но все ошибки в Logcat’е указываются по похожему принципу:
- красный текст;
- тип ошибки — в нашем случае это NumberFormatException;
- пояснение — у нас это For input string: "f";
- ссылка на строку, на которой произошла ошибка — здесь видим MainActivity.java:26.
Исправим эту ошибку и обезопасим себя от некорректного ввода. Добавим в наши поля ввода android:inputType="number", а остальной код оставим без изменений:
Теперь можем вводить только числа. Проверим, как работает равенство: введём одинаковые числа в оба поля. Всё в порядке:
На равенство проверили. Введём разные числа:
Тоже равно. То есть приложение работает, ничего не падает, но результат не совсем тот, который требуется. Наверняка вы и без дебаггинга догадались, в чём ошибка, потому что приложение очень простое, всего несколько строк кода. Но такие же проблемы возникают в приложениях и на миллион строк. Поэтому пройдём по уже известным нам этапам дебаггинга:
- Воспроизведём ошибку: да, ошибка воспроизводится стабильно с любыми двумя разными числами.
- Подумаем, где может быть ошибка: наверняка там, где сравниваются числа. Туда и будем смотреть.
- Исправим ошибку: сначала найдём её с помощью дебаггера, а когда поймём, в чём проблема, — будем исправлять.
И здесь на помощь приходит отладчик. Для начала поставим точки останова сразу в трёх местах:
Чтобы поставить или снять точку останова, достаточно кликнуть левой кнопкой мыши справа от номера строки или поставить курсор на нужную строку, а затем нажать CTRL+F8. Почему мы хотим остановить программу именно там? Чтобы посмотреть, правильные ли числа сравниваются, а затем определить, в какую ветку в нашем ветвлении заходит программа дальше. Запускаем программу с помощью сочетания клавиш SHIFT+F9 или нажимаем на кнопку с жучком:
Появится дополнительное окно, в котором нужно выбрать ваш девайс и приложение:
Вы в режиме дебага. Обратите внимание на две вещи:
- Точки останова теперь помечены галочками. Это значит, что вы находитесь на экране, где стоят эти точки, и что дебаггер готов к работе.
- Открылось окно дебага внизу: вкладка «5: Debug». В нём будет отображаться необходимая вам информация.
Введём неравные числа и нажмём кнопку «РАВНО?». Программа остановилась на первой точке:
Как видим, значения именно такие, какие мы и ввели. Значит, проблема не в получении чисел из полей. Давайте двигаться дальше — нам нужно посмотреть, в правильную ли ветку мы заходим. Для этого можно нажать F8 (перейти на следующую строку выполнения кода). А если следующая точка останова далеко или в другом классе, можно нажать F9 — программа просто возобновит работу и остановится на следующей точке. В интерфейсе эти кнопки находятся здесь:
Остановить дебаггер, если он больше не нужен, можно через CTRL+F2 или кнопку «Стоп»:
В нашем случае неважно, какую кнопку нажимать (F9 или F8). Мы сразу переходим к следующей точке останова программы:
Ветка правильная, то есть логика программы верна, числа firstInt и secondInt не изменились. Зато мы сразу видим, что подпись некорректная! Вот в чём была ошибка. Исправим подпись и проверим программу ещё раз.
Мы уже починили два бага: падение приложения с помощью логов и некорректную логику (с помощью отладчика). Хеппи пас (happy path) пройден. То есть основная функциональность при корректных данных работает. Но нам надо проверить не только хеппи пас — пользователь может ввести что угодно. И программа может нормально работать в большинстве случаев, но вести себя странно в специфических состояниях. Давайте введём числа побольше и посмотрим, что будет:
Не сработало — программа хочет сказать, что 1000 не равна 1000, но это абсурд. Запускаем приложение в режиме отладки. Точка останова уже есть. Смотрим в отладчик:
Числа одинаковые, что могло пойти не так? Обращаем внимание на тип переменной — Integer. Так вот в чём проблема! Это не примитивный тип данных, а ссылочный. Ссылочные типы нельзя сравнивать через ==, потому что будут сравниваться ссылки объектов, а не они сами. Но для Integer в Java есть нюанс: Integer может кешироваться до 127, и если мы вводим по единице в оба поля числа до 127, то фактически сравниваем просто int. А если вводим больше, то получаем два разных объекта. Адреса у объектов не совпадают, а именно так Java сравнивает их.
Есть два решения проблемы:
- Изменить тип Integer на примитив int.
- Сравнивать как объекты.
Не рекомендуется менять тип этих полей в реальном приложении: числа могут приходить извне, и тип лучше оставлять прежним. Изменим то, как мы сравниваем числа:
Всё работает. Наконец-то! Хотя… Давайте посмотрим, что будет, если пользователь ничего не введёт, но нажмёт на кнопку? Приложение опять упало… Смотрим в логи:
Опять NumberFormatException, при этом строка пустая. Давайте поставим точку останова на 26-й строке и заглянем с помощью отладчика глубже.
Нажмём F8 — и перейдём в глубины операционной системы:
Интересно! Давайте обернём код в try/catch и посмотрим ошибке в лицо. Если что, поправим приложение. Выделяем код внутри метода onClick() и нажимаем Ctrl+Alt+T:
Выбираем try / catch, среда разработки сама допишет код. Поставим точку останова. Получим:
Запускаем приложение и ловим ошибку:
Действительно, как и в логах, — NumberFormatException. Метод parseInt выбрасывает исключение, если в него передать пустую строку. Как обрабатывать такую проблему — решать исключительно вам. Два самых простых способа:
- Проверять получаемые строки first.getText().toString() и second.getText().toString() на пустые значения. И если хоть одно значение пустое — говорить об этом пользователю и не вызывать метод parseInt.
- Или использовать уже готовую конструкцию try / catch:
Теперь-то точно всё в порядке! Хотя профессиональным тестировщикам это приложение никто не отдавал: поищете ещё ошибки? :)
Для начала приведу информацию относительно памяти телефона найденую мною на одном из сайтов.
-
3. Internal phone storage ("Внутренняя память телефона")
-
4. MicroSD / SDHC / SDXC . (есть и смартфоны без слота для карты)
На MicroSD-карте можно хранить любые данные в виде файлов (фильмы, музыку, фотографии и так далее). По сути, можно использовать телефон в качестве т.н. "флэшки", то есть в качестве микроSD-карты. В Android 2.2 часть установленных приложений можно перенести из "Внутренняя память" (Internal storage) сюда - на SD-карту; следовательно, это экономит драгоценное пространство "Внутренней памяти" (Internal storage). Но не все приложения могут быть перемещены из "Внутренней памяти" на карту памяти SD. Поэтому даже добавление большой SD-карты не поможет, если "Внутренняя память" близка к заполнению.
При желании заменть SD-карту (например, на другую с большей пропускной способностью), не забудьте отключить ("отмонтировать") текущую SD-карту, прежде чем физически вынимать её: "Настройки" -> "SD-карта и память телефона" -> "SD карта" -> "Отключить SD-Card" (ведь Android основан на Linux-е). Вставленная новая SD-карта будет автоматически установлена ("примонтирована").
Залез в интернет, выяснил, что доступ к Internal storage можно получить имея root права. Станцевал с бубном в течении примерно часов 10, получил на телефоне root права. Как? – не помню. В форуме всё написано, но либо у меня уже мозги не те, либо на форуме пишет народ с не теми мозгами :rolleyes:
С помощью программы Link2SD, перенёс часть программ на карту SD. Это хорошо почистило память. Хватило примерно на месяц. Через месяц СМС опять не приходят.
Начал настраивать себя на снос и переустановку системы, всё не решался >-)
Залез в интернет, выяснил, что есть такие временные файлы с расширением rm. Нашёл их в папке data\local\tmp c помощью программы RootExplorer, удалил – помогло не надолго (объём их был около 3 Мб).
Залез в папку data основательно, прошерстил её различными способами. Нашёл кучу файлов с расширением log, в названии которых присутствует слово error и название различных программ, в том числе тех, которые я удалил давно. Размер каждого из них составлял около 2 Mb, а количество – около 30 шт. Удалил их все. И, о чудо, внутренняя память заполнена 62 Мб из 181 (и телефон работает). Надолго ли? Посмотрим, такое ощущение что чистить надо постоянно.
Хочу начать небольшой разговор о том, как можно получать данные о работе приложения и некоторых его компонентов от пользователей.
Одно дело — разработка, LogCat в Android Studio (если вы из любителей пожестче — можно распечатку в консоли смотреть с помощью adb), и совсем другое — ломать голову над вопросом почему у вас все работает на всем парке тестовых устройств, а пользователь жалуется на абсолютно обратную ситуацию. Коммуникация между разработчиком и конечным пользователем — это хорошо, но совсем другое — видеть своими глазами картинку происходящего (помните, как в матрице — для кого-то это зеленые иероглифы, а для кого-то — женщина в красном?)
Предлагаю разбить задачу на несколько частей, а именно — сбор и хранение логов, способ их передачи из одного приложения в другие с помощью FileProvider, ну и небольшой helper класс для создания писем с аттачами. Итак, поехали.
Кто-то использует System.out.println, кто-то — статические методы класса Log. Я с некоторых пор пришел к написанию своего класса для распечатки логов. Давайте вкратце расскажу почему.
Во-первых, это проще. Как правило, для отслеживания изменений в процессе выполнения приложения я использую одну и ту же метку. И вот однажды я подумал — зачем ты пишешь постоянно Log.i(MY_TAG, «info») если можно сократить немного и убрать из этой формулы одну постоянную?
Во-вторых, расширение логгирования. Это конкретно упирается в нашу задачу — хранение логов в файлах. Можно написать отдельный класс, в который будем передавать какие-то данные, как то: данные и имя файла, но данные мы уже передаем в метод Log.i / Log.e / проч., создавать лишний раз переменную что ли для этого? Некрасиво все это как-то.
Ладно, довольно лирики, давайте лучше взглянем на класс Diagnostics.
Для того, чтобы вывести информацию в LogCat с дефолтной меткой, достаточно написать следующее:
Иногда мне хочется видеть какие методы вызываются и в каких объектах. И с какими параметрами или значениями переменных. В общем, тут важно для меня — где именно производится вызов. Тогда я использую следующую конструкцию
Diagnostics.i(this, “onCreate w/param1 = “ + param1);
где this — это экземпляр класса Caller. Например, для MainActivity вы увидите следующее:
03–29 12:31:53.203 16072–16072/com.isidroid.platform I/Diagnostics: MainActivity.onCreate w/param1 = 200
И все сразу становится понятно — кто вызывает и где вызывает.
А теперь о хранении этой информации.
Как вы уже могли видеть, в классе Diagnostics есть методы для работы с файлами — createLog и appendLog. Объяснять, я думаю, не стоит — первый создает файл, второй — добавляет в него строку. Для новичков или тех, кто ленится читать код, уточню — appendLog создает файл, если его не существует, а createLog всегда создает новый. Чтобы лишней информации там не хранилось.
Файлы хранятся в cache директории, которая, к слову, недоступна для других приложений (ну, если у вас телефон не рутован, конечно).
В общем, теперь процедура распечатки лога и хранения его в файле выглядит следующим образом.
Надеюсь, это выглядит просто в использовании.
Как я уже говорил выше, наши файлы для лога хранятся в некоторой защищенной от чужих глаз папке. Она настолько защищена, что если вы попробуете передать файлы в другое приложение с использованием относительного пути File.getAbsolutePath(), то вы потерпите неудачу.
На помощь к нам мчится FileProvider, друзья!
2. Указываем директории, доступные для шаринга. Для этого создаем файл res/xml/cache_file_paths и для нашего конкретного примера заполняем его.
Конец.
Нет, правда, это все.
На самом деле это довольно мощный инструмент для работы с файлами в вашем приложении, но в рамках поставленной задачи это все, что нам нужно сделать. Подробности — в официальной документации.
Мы с вами почти добрались до конца, осталось дело за малым. Вообще, создание намерения (intent) для отправки писем — это довольно тривиальная задача, чтобы под нее писать отдельный хелпер. Но с другой стороны, если можно причесать код в вашей Activity / Fragment, то почему бы и нет, верно?
Гораздо симпатичнее будет выглядеть какой-нибудь строитель (builder) в коде нежели условия, проверки и лишние циклы. Я за то, чтоб это выносить в отдельный класс (кстати, не только я ратую за разделение представления от бизнес-логики).
Давайте перейдем сразу к сути. Сначала я покажу класс (который вы можете скопировать и использовать не глядя, конечно), а потом пример его использования. Поехали!
Где this — это Activity.
Вы можете самостоятельно указать «рыбу» для текста письма, но я рекомендую использовать те данные, которые указаны в методе buildContent, расширяя их при необходимости. Можно конечно извернуться и применить паттерн «декоратор» для расширения этих данных без модификации класса FeedbackHelper, но лично для меня необходимости в этом не было… Что до вас, то дерзайте!
Кто бы что ни говорил, но Google Play – это помойка. Не даром её признали самым популярным источником вредоносного софта для Android. Просто пользователи в большинстве своём доверяют официальном магазину приложений Google и скачивают оттуда любое ПО без разбору. А какой ещё у них есть выбор? Ведь их всегда учили, что скачивать APK из интернета куда опаснее. В общем, это действительно так. Но остерегаться опасных приложений в Google Play нужно всегда. По крайней мере, постфактум.
Есть как минимум 8 приложений, которые нужно удалить
Google добавила в Google Play функцию разгона загрузки приложений
Вредоносные приложения для Android
Нашли вирус? Удалите его
В основном это приложения, которые потенциально высоко востребованы пользователями. Среди них есть скины для клавиатуры, фоторедакторы, приложения для создания рингтонов и др.:
- com.studio.keypaper2021
- com.pip.editor.camera
- org.my.famorites.up.keypaper
- com.super.color.hairdryer
- com.celab3.app.photo.editor
- com.hit.camera.pip
- com.daynight.keyboard.wallpaper
- com.super.star.ringtones
Это названия пакетов приложений, то есть что-то вроде их идентификаторов. Поскольку всё это вредоносные приложения, их создатели знают, что их будут искать и бороться с ними. Поэтому они вполне могут быть готовы к тому, чтобы менять пользовательские названия приложений, которые видим мы с вами. Но это мы не можем этого отследить. Поэтому куда надёжнее с этой точки зрения отслеживать именно идентификаторы и удалять вредоносный софт по ним.
Как найти вирус на Android
Но ведь, скажете вы, на смартфоны софт устанавливается с пользовательскими названиями. Да, это так. Поэтому вам понадобится небольшая утилита, которая позволит вам эффективно выявить весь шлаковый софт, который вы себе установили, определив название их пакетов.
- Скачайте приложение для чтения пакетов Package Name Viewer;
- Запустите его и дайте те привилегии, которые запросит приложение;
В красном квадрате приведен пример названия пакета
- Поочерёдно вбивайте в поиск названия пакетов, приведённые выше;
- При обнаружении приложений с такими именами, нажимайте на них и удаляйте.
Package Name Viewer удобен тем, что позволяет не просто найти нужное приложение по названию его пакета, но и при необходимости перейти в настройки для его удаления. Для этого достаточно просто нажать на иконку приложения, как вы попадёте в соответствующий раздел системы, где сможете остановить, отключить, удалить накопленные данные, отозвать привилегии или просто стереть нежелательную программу.
Как отменить подписку на Андроиде
Лучше всего приложение именно удалить. Это наиболее действенный способ защитить себя от его активности. Однако не исключено, что оно могло подписать вас на платные абонементы, поэтому для начала проверьте свою карту на предмет неизвестных списаний, а потом просмотрите список действующих подписок в Google Play:
- Запустите Google Play и нажмите на иконку своего профиля;
- В открывшемся окне выберите раздел «Платежи и подписки»;
- Здесь выберите «Подписки» и проверьте, нет ли среди них неизвестных;
- Если есть, просто нажмите напротив неё на кнопку «Отменить».
Свободное общение и обсуждение материалов
Можно ли танцевать под рэп? Достаточно послушать новый альбом Sfera EbbastaНесмотря на то что мобильный Google Chrome куда менее ресурсоёмок, чем десктопный, он тоже имеет свойство засоряться. Со временем браузер кэширует так много данных, что объём, который он занимает на смартфоне, разрастается до нескольких гигабайт. Работать медленнее от этого он, к счастью, не начинает, однако начинает смущать пользователей слишком уж большим весом. Ведь не может обычный браузер весить по 3-5 ГБ, в то время как даже самые топовые игры занимают в несколько раз меньше места.
Долгое время все приложения, которые выпускала Apple, предназначались только для iOS. Несмотря на то что было бы логично выйти на рынок Android, предложив пользователям вражеской платформы приобщиться к по-настоящему удобным сервисам, в Купертино этого не делали. Однако желание переманить фанатов ОС от Google к себе не покидало Apple. Поэтому было решено действовать радикальным образом сразу, предложив пользователям Android приложение по переходу на iOS, которое позволяло с лёгкостью выполнить переезд. Но теперь оно будет ещё лучше.
Делать скриншоты - нормальное явление. Это проще, чем копировать текст, пересказывать чей-то диалог или запоминать какое-то задание по работе. С развитием технологий скриншоты стало делать гораздо удобнее - достаточно лишь зажать необходимую комбинацию клавиш на смартфоне и изображение экрана сохранится в вашей медиатеке. Сейчас скриншоты стали частью нашей жизни и целым жанром: о них снимают фильмы и за счет них процветают целые сообщества в социальных сетях. Но так ли это безопасно? Почему скриншоты вредят отношениям между людьми? Как сделать скриншот и никого не обидеть?
“пользователи в большинстве своём доверяют официальном магазину приложений Google и скачивают оттуда любое ПО без разбору”, зачем судить по себе? Никто так не делает и вообще откуда этот дикий список того, что надо удалить?
Читайте также: