Add problem in android

Методы лечения различных ошибок в Android Studio при разработке проекта

Сегодня хотел бы поделиться своим анализом и способами лечением разных ошибок при разработке своего продукта в Android Studio. Лично я, не раз сталкивался с различными проблемами и ошибками при компиляции и/или тестировании мобильного приложения. Данный процесс, всегда однообразный и в 99% случаев и всегда нужно тратить n-колличество времени на его устранение. Даже, когда ты уже сталкивался с данной проблемой, ты все равно идешь в поисковик и вспоминаешь, как же решить ту или иную ситуацию.

Я для себя завел файлик, в котором отметил самые частые ошибки — потратив на это несколько часов и перечислил самые популярные ошибки (в дальнейшем планирую просто их запомнить), чтоб сократить свое время в дальнейшем.

Итак, начну по порядку с самой распространенной проблемы и дальше буду перечислять их по мере появления:

1) Если подчеркивает красным код, где используются ресурсы: R. — попробовать (но вероятно не поможет): Build -> Clean Project.

В принципе на Build -> Clean Project можно не терять времени, а лучше всего — слева переключиться на Project, открыть каталог .idea, затем каталог libraries и из него удалить все содержимое. Затем нажать кнопку Sync Project. А затем (если все еще красное, но скорее всего уже будет все ок ) Build -> Clean Project.

2) После внезапного выключения компьютера, после перезапуска может быть во всех проектах весь код красным. Перед этим может быть ошибка: Unable to create Debug Bridge: Unable to start adb server: Unable to obtain result of ‘adb version’. Есть три решения — первое помогло, второе нет (но может быть для другого случая), а третье — не пробовал:

а) File — Invalidate Caches/Restart — Invalidate and Restart

б) Закрыть студию. В корне папки проекта удалить файл(ы) .iml и папку .idea. Вновь запустить студию и импортировать проект.

в) Нажать Ctrl-Alt-O и запустить оптимизацию импорта.

Кстати, adb сервер можно проверить на версию (и работоспособность) и затем перезапустить:

3) Если Android Studio выдает приблизительно такую ошибку: Error:Execution failed for task ‘:app:dexDebug’.

Надо слева переключиться на опцию Project, найти и удалить папку build которая лежит в папке app, т.е. по пути app/build. Затем перестроить весь проект заново: Build -> Rebuild Project.

Такое же решение если ошибка типа: «не могу удалить (создать) папку или файл» и указан путь, который в ведет в app/build. Тоже удаляем папку build и ребилдим проект.

4) В сообщении об ошибке упоминается heap — виртуальная память. А ошибка обычно вызвана ее нехваткой, т.е. невозможностью получить запрашиваемый объем. Поэтому этот запрашиваемый объем надо уменьшить, т.е. переписать дефолтное значение (обычно 2048 MB которое можно изменить в настройках), на меньшее 1024 MB.

В файле проекта gradle.properties пишем:

5) Android Studio пришет примерно такую ошибку: Plugin is too old, please update to a more recent version, or set ANDROID_DAILY_OVERRIDE environment variable to «83648b99316049d63656d7276cb19cc7e95d70a5»

Возможные причины (кроме необходимости регулярного обновления SDK):

а) Загруженный проект был скомпилирован с помощью уже несовместимого старого gradle плагина. В этом случае надо найти и подключить в своем build.gradle проекта этот более старый плагин. т.е. попробовать более старые версии, например: 1.1.3 (часто именно 1.1.x и подходит).

Найти все версии можно здесь.

б) Если в build.gradle проекта используется beta-версия плагина — это означает, что срок ее истек. Посмотреть последние релизы (продакшн и бета) можно также здесь:

6) Иногда при подключении сторонних библиотек могут дублироваться некоторые файлы (обычно связанные с лицензированием). В сообщении будет что-то содержащее слова: duplicate files. Решение — надо посмотреть в сообщении об ошибке или в документации подключенной сторонней библиотеки — какие именно файлы стали избыточными, и перечислить их в build.gradle модуля для исключения (exclude) из билда.

Это делается в директиве packagingOptions (которая, в свою очередь, находится в директиве android).

Источник

Обновляемся на новую версию API Android по наставлению Google

Скоро выходит Android 12, но в этом августе уже с 11-й версии разработчикам придётся использовать новые стандарты доступа приложений к внешним файлам. Если раньше можно было просто поставить флаг, что ваше приложение не поддерживает нововведения, то скоро они станут обязательными для всех. Главный фокус — повышение безопасности.

Переход на новую версию API — довольно трудоёмкая операция, требующая больших затрат на её поддержку при введении крупных апдейтов. Далее расскажу немного про наш переход и возникшие при этом трудности.

Что происходит

Если вы уже знакомы с теорией, то этот раздел можно пропустить — тут я хочу поверхностно сравнить подходы к предмету в разных версиях операционной системы.

Читайте также:  The first tree андроид

В Android есть внутреннее Internal Storage (IS) и внешнее хранилище External Storage (ES). Исторически это были встроенная память в телефоне и внешняя SD-карта, поэтому ES был больше, но медленнее и дешевле. Отсюда и разделение — настройки и критически важное записывали в IS, а в ES хранили данные и большие файлы, например, медиа. Потом ES тоже стал встраиваться в телефон, но разделение, по крайней мере логическое, осталось.

У приложения всегда есть доступ к IS, и там оно может делать что угодно. Но эта папка только для конкретного приложения и она ограничена в памяти. К ES нужно было получать доступ и, кроме манипуляции со своими данными, можно было получить доступ к данным других приложений и производить с ними любые действия (редактировать, удалять или украсть).

Но после разделения на внутреннее и внешнее хранилища все равно оставались проблемы. Многие приложения могли хранить чувствительную информацию не только в IS, но и в ES — то есть ответственность лежала целиком на разработчиках и на том, кто хочет завладеть файлами.

В Android решили всё это переделать ещё в 10-й версии, а в 11-й это стало обязательным.

Чтобы минимизировать риски для пользователя в Google решили внедрить Scoped Storage (SS) в ES. Возможность проникнуть в папки других приложений убрали, а доступ есть только к своим данным — теперь это сугубо личная папка. А IS с 10-й версии ещё и зашифрована по умолчанию.

В Android 11 Google зафорсировала использование SS — когда таргет-версия SDK повышается до 30-й версии API, то нужно использовать SS, иначе будут ошибки, связанные с доступом к файлам. Фишка Android в том, что можно заявить совместимость с определённой версией ОС. Те, кто не переходили на 11, просто говорили, что пока не совместимы с этой версий, но теперь нужно начать поддерживать нововведения всем. С осени не получится заливать апдейты, если не поддерживаешь Android 11, а с августа нельзя будет заливать новые приложения.

Если SS не поддерживается (для девайсов ниже 10-й версии), то для доступа к данным других приложений требуется получить доступ к чтению и записи в память. Иначе придётся получать доступ к файлам через Media Content, Storage Access Framework или новый, появившийся в 11-м Android, фреймворк Datasets в зависимости от типа данных. Здесь тоже придётся получать разрешение доступа к файлу, но по более интересной схеме. Когда расшариваемый файл создаёшь сам, то доступ к нему не нужен. Но если переустановить приложение — доступ к нему опять потребуется. К каждому файлу система привязывает приложение, поэтому когда запрашиваешь доступ, его может не оказаться. Особо беспокоиться не нужно, это сложно отследить, поэтому лучше просто сразу запрашивать пермишен.

Media Content, SAF и Datasets относятся к Shared Storage (ShS). При удалении приложения расшаренные данные не удаляются. Это полезно, если не хочется потерять нужный контент.

Хотя даже при наличии SS можно дать доступ к своим файлам по определённой технологии — через FileProvider можно указать возможность получения доступа к своим файлам из другого приложения. Это нормально, потому что файлы расшаривает сам разработчик.

Также добавилась фича — если приложение не использовалось несколько месяцев, то снимаются все пермишены и доступы к системным элементам. По best practice разрешение запрашивается по необходимости (то есть непосредственно перед использованием того, на что спрашиваем разрешение), поэтому мы просто перед выполнением какого-либо действия проверяем, есть ли у нас пермишены. Если нет, то запрашиваем.

В то же время перекрыли доступы к приложениям внутри девайса. Если раньше можно было отследить, что установлены определённые приложения и отправлять к ним соответствующие интенты, то сейчас мы должны прямо в манифесте прописать, что работаем именно с этими приложениями, и только после этого получить доступ.

В качестве примера можем взять шаринг — мы шарим множество приложений, и их всех нужно указывать в манифесте, иначе они не обнаружатся. Начнём перебирать пакет установленных приложений — будет информация, что не указанного в манифесте приложения нет и при шаринге всё отвалится.

Перейдём к практике.

Переход на новую версию

Основная функциональность по работе с файлами в приложении iFunny представлена в виде сохранения мемов в память и расшаривания их между приложениями. Это было первое, что требовалось починить.

Для этого выделили в общий интерфейс работу с файлами, реализация которого зависела от версии API.

FilesManipulator представляет собой интерфейс, который знает, как работать с файлами и предоставляет разработчику API для записи информации в файл. Copier — это интерфейс, который разработчик должен реализовать, и в который передаётся поток вывода. Грубо говоря, мы не заботимся о том, как создаются файлы, мы работаем только с потоком вывода. Под капотом до 10-й версии Android в FilesManipulator происходит работа с File API, после 10-й (и включая её) — MediaStore API.

Читайте также:  Настройки build prop android

Рассмотрим на примере сохранения картинки.

Так как операция сохранения медиафайлов достаточно длительная, то целесообразно использовать MediaStore.Images.Media.IS_PENDING , которая при установлении значения 0 не дает видеть файл приложениям, отличного от текущего.

По сути, вся работа с файлами реализована через эти классы. Шаринг в другие приложения автоматически сохраняют медиа в память устройства и последующая работа с URI уже происходит по новому пути. Но есть такие SDK, которые ещё не успели перестроиться под новые реалии и до сих пор используют File API для проверки медиа. В этом случае используем кеш из External Storage и при необходимости провайдим доступ к файлу через FileProvider API.

Помимо ограничений с памятью в приложениях, таргетированных на 30-ю версию API, появилось ограничение на видимость приложения. Так как iFunny использует шаринг во множество приложений, то данная функциональность была сломана полностью. К счастью, достаточно добавить в манифест query, открывающую область видимости к приложению, и можно будет также полноценно использовать SDK.

Для неявных интентов тоже приходится добавлять код в манифест, чтобы задекларировать то, с чем будет работать приложение. В качестве примера выложу часть кода, добавленного в манифест.

После проверок запуска UI-тестов на девайсах с версиями API 29-30 было выявлено, что они также перестали корректно отрабатываться.

Первоначально в LogCat обнаружил, что приложение не может приконнектиться к процессу Orchestrator и выдает ошибку java.lang.RuntimeException: Cannot connect to androidx.test.orchestrator.OrchestratorService.

Эта проблема из разряда видимости других приложений, поэтому достаточно было добавить строку

Тест удачно запустился, но возникла другая ошибка — Allure не может сохранить отчёт в память устройства, падает с ошибкой.

Очевидно из-за Scoped Storage стало невозможно сохранять файлы в другие папки, поэтому снова почитав документацию по управлению файлами в памяти на девайсе, обнаружил интересный раздел. Там рассказано, как для нужд тестов открыть доступ к папкам девайса, но с существенными ограничениями, которые можно почитать тут.

Так как нам нужно использовать этот пермишен только для тестов, то нам условия подходят. Поэтому я быстренько написал свой ShellCommandExecutor, который выполняет команду adb shell appops set —uid PACKAGE_NAME MANAGE_EXTERNAL_STORAGE allow на создании раннера тестов.

На Android 11 тесты удачно запустились и стали проходить без ошибок.

После попытки запуска на 10-й версии Android обнаружил, что отчет Allure также перестал сохраняться в память девайса. Посмотрев issue Allure, обнаружил, что проблема известная, как и с 11-й версией. Достаточно выполнить команду adb shell appops set —uid PACKAGE_NAME LEGACY_STORAGE allow . Сказано, сделано.

Запустил тесты — всё еще не происходит сохранения в память отчёта. Тогда я обнаружил, что в манифесте WRITE_EXTERNAL_STORAGE ограничен верхней планкой до 28 версии API, то есть запрашивая работу памятью мы не предоставили все разрешения. После изменения верхней планки (конечно, для варианта debug) и запроса пермишена на запись тесты удачно запустились и отчёт Allure сохранился в память устройства.

Добавлены следующие определения пермишенов для debug-сборки.

После всех вышеописанных манипуляций с приложением, можно спокойно устанавливать targetSdkVersion 30, загружать в Google Play и не беспокоиться про дедлайн, после которого загружать приложения версией ниже станет невозможно.

Источник

📱8 распространенных ошибок в разработке под Android

Перевод публикуется с сокращениями, автор оригинальной статьи Siva Ganesh Kantamani .

1. У всего есть свое место, но не все это понимают

Экосистема Android быстро развивается и включает всевозможные сообщества по всему миру : разные социальные слои, пользователи с ограниченными возможностями, желающие иметь модные фичи люди и многие другие.

Разработка приложений для такого разнообразия – непростая задача. Речь не об архитектуре высокого уровня, а о простых вещах, значительно влияющих на современную Android-разработку: strings, colors, dimens и т. д.

Важно сохранить все строковые ресурсы в одном файле (обычно strings.xml) для быстрого редактирования. Это применимо к цветам, ресурсам dimens и стилям, поэтому, когда придет время добавить dark mode , с этим будет легко справиться.

Вывод: поддерживайте код в одном месте для повторного использования и не пишите хардкод.

2. Отказ от использования фрагментов

В начале пути разработки под Android рекомендовалось использовать отдельные activities для каждого экрана. С течением времени стали всплывать различные проблемы из-за этого. Кроме того, являющиеся точками входа в приложение активити имели массу уязвимостей.

С другой стороны, использование activities имело смысл несколько лет назад, когда API Fragments еще не был допилен.

Сегодня команда Android рекомендует использовать фрагменты для проектирования каждого экрана и поддерживать одно или несколько активити во всем приложении для их размещения. Такое построение имеет название Single Activity Architecture .

Новый подход значительно сокращает количество обращений извне приложения. Одной из основанных на архитектуре единой активности новинок является навигационный компонент Jetpack .

Вывод: используйте API Fragments – это сделает вашу жизнь намного проще.

3. Нежелание использовать DataBindings или ViewBindings

Среда разработки Android была основана на трех типах файлов: XML, Kotlin и Java. XML-файлы содержат все, что связано с дизайном, а файлы Kotlin/Java включают в себя остальные части приложения.

Дизайн и прочие части должны быть связаны, и именно здесь data binding и view binding играют ключевую роль вместе с функцией findviewbyid. Основная цель view binding – решить проблему безопасности биндинга в рантайме.

Читайте также:  Асус трансформер тф 101 как обновить андроид

Цель data binding – привязка компонентов UI в макетах к источникам данных, с использованием декларативного формата, а не программного.

Вывод: рассмотренные инструменты повысят уровень безопасности приложения и добавят простоты в обработке UI.

4. Нежелание использовать Kotlin и Coroutines

В тот момент, когда ребята из Google объявили Kotlin рекомендуемым языком для разработки приложений для Android, это стало влияющим на болевые точки в Java и снижающим нагрузку на разработчиков шагом.

Использование Kotlin открыло доступ к таким функциям, как extensions, scoped functions, data classes, object keyword, null safety и т. д. От разработки для Android , вы можете перейти к мультиплатформенной и серверной разработке.

Асинхронное программирование играет ключевую роль в создании приложений. На ранних стадиях для этого применялся AsyncTask, а со временем произошел переход на RxJava.

Затем появились корутины – простой подход к асинхронному программированию. В наши дни они стали стандартным решением для реализации многих задач. Kotlin делает разработку простой и лаконичной, а корутины позволяют выполнять асинхронные задачи последовательно, без необходимости изучать что-либо новое.

Вывод: для работы с асинхронностью используйте корутины, а не AsyncTask. Нам нужна производительность и надежность.

5. Ошибки проектирования

ConstraintLayout поставляется с удобными функциями: guidelines , barriers , group , aspect ratio , flow , layer и т. д. Благодаря этим функциям на нем можно построить практически любой экран.

ConstraintLayout отличается от Relative и Linear layout . Вы можете создать плоские макеты без иерархии вложенности, что приведет к меньшему количеству слоев для рисования во view .

Чрезмерное использование ConstraintLayout

Мощные функции данного инструмента совсем необязательно применять на каждом шагу. Использование ConstraintLayout в создании UI, который зачастую можно спроектировать с помощью FrameLayout или LinearLayout , является избыточным.

ConstraintLayout – это правильный выбор для разработки сложных вариантов интерфейса, но не для реализации анимации и переходов – для этого используйте MotionLayout .

MotionLayout – это подкласс ConstraintLayout, включающий все его функции. Он полностью декларативен с возможностью реализации сложных переходов в XML и обратно и совместим с API уровня 14, что делает его универсальным для 99% случаев использования. Новый редактор MotionLayout в Android Studio 4.0 позволяет легко с ним работать.

Вывод: для каждой конкретной ситуации выбирайте правильный инструмент, что позволит избежать лишней обработки и рефакторинга.

6. Отсутствие знаний о безопасности

Хранение конфиденциальных данных

Хранение конфиденциальных данных в shared preference, БД или локальном хранилище – рискованная затея, т. к. их все можно легко взломать. Многие разработчики не знают об этом и используют shared preference для хранения паролей, настроек и прочей информации пользователей.

Это можно решить с помощью новой библиотеки хранилища , используя Encrypted preference или путем реализации шифрования самостоятельно.

Многие разработчики считают, что использование HTTPS может обезопасить связь с серверами, но это не всегда так. Зачастую хакеры вмешиваются в канал связи, чтобы скомпрометировать всех участников. Это называется атакой man in the middle . Для установки защищенной линии связи с сервером, придется установить и настроить сертификат.

Вывод: не пренебрегайте безопасностью и применяйте советы только из официального хелпа.

7. Незнание возможностей Android Studio

Не имеет значения, насколько мощным будет оружие, если вы не научитесь правильно его применять. Как разработчикам вам повезло иметь возможность использовать Android Studio, но вам придется его изучить.

В Android Studio есть много скрытых функций : handy shortcuts , live templates , file templates, predefined project structures, code generator plug-ins, customization и многие другие . У нас также есть database inspector, layout inspector, profiler и другие фичи для продуктивности в рантайме.

Android Studio также предоставляет инструментальную поддержку для нескольких библиотек, вроде navigation editor для просмотра навигационного графика приложения, и motion editor для реализации эффективной анимации и переходов.

Вывод: студия снабжена столькими полезными плюшками, что не изучить их и не использовать было бы глупо.

8. Игнорирование библиотеки Jetpack

Jetpack – это набор библиотек, которые помогают разработчикам следовать лучшим практикам, сокращать шаблонный код и писать приложения, стабильно работающие на любых устройствах и версиях Android.

Библиотека охватывает следующие функции:

  • paging3 для разбиения на страницы;
  • Room для локальной базы данных;
  • WorkManager для длительных фоновых задач;
  • DataStore для улучшенного хранения данных;
  • Hilt для DI;
  • App Startup для сокращения времени запуска приложения и т. д.

Все эти компоненты созданы с учетом производительности и простоты использования для реализации сложных задач с минимальным количеством кода.

Вывод: библиотека – это дополнительные возможности для вашего кода, зачастую очень полезные.

Заключение

Естественно, это далеко не все известные просчеты. Не печальтесь, что у вас бывают ошибки, не бойтесь их допускать и не опускайте руки, если их слишком много, поскольку любое обучение проходит через «боль и огорчение».

Изучайте учебные материалы, смотрите видео с конференций и онлайн-курсов, старайтесь посещать митапы и прочие мероприятия, общайтесь с единомышленниками и черпайте опыт – только так можно набить руку и получить заветный опыт. Удачи в обучении!

Источник

Оцените статью