- Методы лечения различных ошибок в Android Studio при разработке проекта
- Android in-app purchases, часть 4: коды ошибок от Billing Library и как не облажаться с тестированием
- Коды ошибок
- Самая популярная ошибка
- Заключение
- Про Adapty
- Самые частые ошибки начинающих Android разработчиков
- Использование интерфейсных решений, характерных для iOS
- Неиспользование интентов
- Неиспользование fragments
- Разработка для текущей версии Android
- Разработка для одного или двух экранов
- Блокирование основного (UI) потока
- Пренебрежение документацией
- Глубокая иерархия в макетах экранов
- Неправильное использование картинок
- Мобильное приложение не маленький проект
- Заключение
Методы лечения различных ошибок в 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).
Источник
Android in-app purchases, часть 4: коды ошибок от Billing Library и как не облажаться с тестированием
Привет, я Влад, core разработчик Adapty SDK для Android. Продолжаю серию статей про то, как внедрять внутренние покупки в приложение Google Play. Остальные посты можно найти по ссылкам:
Android in-app purchases, часть 4: коды ошибок от Billing Library и как не облажаться с тестированием. — Вы тут.
Сегодня мы поговорим о кодах ошибок, которые мы можем получить от Billing Library в методе getResponseCode().
Пример того, как мы передавали ошибки в свои колбэки, можно посмотреть в этой статье. С одной ошибкой мы уже знакомы по предыдущим статьям — это USER_CANCELED, когда пользователь закрывает диалог покупки, ничего не купив. Давайте познакомимся с остальными.
Коды ошибок
Начнем с самых простых ошибок – с говорящим названием ERROR (responseCode 6) и чуть более говорящим названием DEVELOPER_ERROR (responseCode 5). Для первого случая гугл пишет в документации «Fatal error during the API action», для второго – «Invalid arguments provided to the API». Например, я смог получить DEVELOPER_ERROR, когда для запроса querySkuDetailsAsync() в билдер в setType() передал пустую строку.
Но не всё так просто. Я пошел дальше и в методе launchBillingFlow() использовал измененный SkuDetails (вытащил json из SkuDetails реального продукта, поменял в нем productId и передал в конструктор новому SkuDetails). По сути это invalid argument, и я ожидал получить DEVELOPER_ERROR, но… получил ERROR.
Отдельного упоминания заслуживает текст, который показывается в диалоге в этом кейсе — сравните английский и русский вариант:
Это, конечно, был искусственный пример. Гораздо ближе к реальности кейс, когда гугл отклонил оплату. Если при тестировании покупок с тестовой карты, о чем мы расскажем в конце статьи, в диалоге покупки выбрать «test card, always declined», вернется также ошибка ERROR, но уже с адекватным текстом.
В третьей статье, где описывалась смена подписки, мы для одного из proration mode увеличили цену годовой подписки почти в 3 раза, но не сказали, какая там должна была быть ошибка, если бы мы этого не сделали. Исправляемся.
Так как там, получается, указан неправильный proration mode, по логике мы должны получить всё ту же DEVELOPER_ERROR. Но нет, мы получаем SERVICE_UNAVAILABLE (responseCode 2). Ее же мы получаем и если указать любое левое число в качестве proration mode (это int, а не enum, нас никто не остановит), и если указать неправильный purchaseToken. Смотрим в документацию про SERVICE_UNAVAILABLE – «Network connection is down». Так, стоп…
При этом еще мы видим интересный диалог.
Что еще любопытно – в кейсе с ERROR при закрытии диалога НЕ через кнопку «ОК» (то есть, теми способами, которые интерпретируются как возврат назад) в onPurchasesUpdated() пришло, собственно, ERROR, а в случае с SERVICE_UNAVAILABLE в аналогичном кейсе приходит USER_CANCELED (но если нажать «ОК» в диалоге, то мы, как и ожидали, получим SERVICE_UNAVAILABLE).
Ну и в случае с отсутствием интернета SERVICE_UNAVAILABLE тоже приходит, тут не соврали.
Вот остальные коды ошибок с небольшими комментариями, так сказать, honorable mentions.
BILLING_UNAVAILABLE (responseCode 3). Гугл поясняет, что «Billing API version is not supported for the type requested». Я смог воспроизвести эту ошибку, разлогинившись из Google-аккаунта, а также на Хуавее без Google Play Services. Возможно, она также воспроизведется на старых телефонах, где не обновляли Google Play.
SERVICE_DISCONNECTED (responseCode -1). Приложение иногда дисконнектится от сервиса Google Play. Это может произойти, если Play Store вдруг решит обновиться. Поэтому лучше перестраховаться и коннектиться перед каждым вызовом методов Billing Library, как в предыдущих статьях. А еще мы с гуглом советуем добавить какую-нибудь retry policy, если эта ошибка всё же придет в ответе.
SERVICE_TIMEOUT (responseCode -3). Название говорит само за себя — мы слишком долго ждали ответ от Google Play.
FEATURE NOT SUPPORTED (responseCode -2). В классе BillingClient есть пять констант FeatureType. Их доступность на данном устройстве можно проверять с помощью метода billingClient.isFeatureSupported(BillingClient.FeatureType.НужнаяФича). У меня на телефоне (Xiaomi Mi A2 Lite) FEATURE_NOT_SUPPORTED вернулось только для SUBSCRIPTIONS_ON_VR. При этом для IN_APP_ITEMS_ON_VR, как и для всех остальных фич, вернулось OK.
ITEM_NOT_OWNED (responseCode 8). Возникает при попытке законсьюмить покупку, которой у нас нет. Например, повторно после успешного консьюма.
ITEM_ALREADY_OWNED (responseCode 7). А тут наоборот – при попытке купить продукт, который у нас уже есть. В таком кейсе просто нужно обновить UI и сделать кнопку покупки некликабельной.
Самая популярная ошибка
Последняя и, наверное, самая популярная ошибка в начале пути внедрения in-app purchases — это ITEM_UNAVAILABLE (responseCode 4). Она говорит о том, что продукт недоступен для покупки, но не говорит, почему. А причины могут быть самые разные: от тестирования на неправильном аккаунте или неправильной сборке до покупки неактивированного продукта.
Вот чек-лист, что нужно сделать, чтобы избежать ее при тестировании:
Отправить в ваш test track сборку с Billing Library. Это обязательное условие — при этом вы можете тестировать и на дебажных сборках с таким же applicationId, но важно, чтобы хотя бы один раз сборка с Billing Library была загружена в Play Console.
Добавить в этот test track гугл-аккаунты тестировщиков, что особенно актуально для internal testing или закрытой альфы/беты. Там же будет ссылка в разделе How testers join your test, по которой тестировщики должны будут принять приглашение.
Покупать можно только активированный продукт. После создания продукта в Play Console есть кнопка activate, более детально процесс создания продукта мы описывали в первой статье.
Удостовериться, что тестирование на устройстве проходит с гугл-аккаунта, который является тестировщиком. Очевидный пункт, но бывает всякое, и это тоже нужно проверить, если вы получили такую ошибку.
applicationId сборки, с которой тестируется покупка, должно полностью совпадать с applicationId из Play Console. Это особенно важно для тех, у кого добавляется суффикс в дебажных сборках.
Добавить email-адреса тестировщиков в раздел Setup → License Testing в левом меню аккаунта (не приложения), чтобы они покупали продукты бесплатно с тестовой карты, а не с реальной. Еще один плюс, что подписки в данном случае будут иметь тестовую длительность. Не связано с этой ошибкой, но тоже полезное знание.
Заключение
Ошибки способны сильно усложнить работу, поэтому всегда важно понимать, как они могут возникнуть. Учитывая, сколько шагов нужно пройти, чтобы получить доступ к продуктам, проще всего словить ITEM_UNAVAILABLE. Поэтому я надеюсь, что мой чек-лист вам поможет.
Про Adapty
Для более простой работы с ошибками советую попробовать Adapty SDK для внедрения внутренних покупок в приложения. Кроме технической части, Adapty даёт много преимуществ:
Встроенная аналитика позволяет быстро понять основные метрики приложения.
Когортный анализ отвечает на вопрос, как быстро сходится экономика.
А/Б тесты увеличивают выручку приложения.
Интеграции с внешними системами позволяют отправлять транзакции в сервисы атрибуции и продуктовой аналитики.
Промо-кампании уменьшают отток аудитории.
Open source SDK позволяет интегрировать подписки в приложение за несколько часов.
Серверная валидация и API для работы с другими платформами.
Познакомьтесь подробнее с этими возможностями, чтобы быстрее внедрить подписки в своё приложение и улучшить конверсии.
Источник
Самые частые ошибки начинающих Android разработчиков
Android воистину фантастическая платформа для разработчика. Судите сами: исходный код android открыт, все инструменты разработки бесплатны, вы можете использовать их на любой операционной системе, Android хорошо документирован, процесс распространения и продажи приложений очень прост и хорошо описан. С момента выхода на рынок в 2008 году Android проделал большой путь. Сегодня вы можете пользоваться различными IDE для написания своих программ, но с недавнего времени единственной поддерживаемой Google средой является Android Studio, которая в свою очередь базируется на IntelliJ IDE. Android Studio делает многое для упрощения жизни разработчика, однако даже очень продвинутая IDE не способна заменить программисту голову, и в нашем коде по прежнему встречаются баги. В этой статье будут указаны наиболее характерные ошибки Android разработчиков. Конечно, наиболее часто они встречаются в коде новичков, однако и опытные программисты иногда встречаются с этими граблями.
Использование интерфейсных решений, характерных для iOS
Android и iOS активно конкурируют на рынке мобильных операционных систем. Многие разработчики пришли в Android из мира Apple. Не удивительно, что оказавшись в новой среде они пытаются использовать свой предыдущий опыт. Android и iOS имеют много общего, однако некоторые интерфейсные решения для них сильно отличается. Поэтому прежде чем начать разрабатывать Android приложения было бы неплохо ознакомиться с «Android design guidelines». Это поможет Вам понять экосистему Android, и вы не напугаете своих пользователей «нелогичным» интерфейсом.
Неиспользование интентов
Интенты — это одна из ключевых идей системы Android. С их помощью можно запросить данные или выполнение действий от других компонентов системы. Причем, вы можете обратиться как к частям собственной программы, так и к внешнему приложению. Современные программы многофункциональны, и вместо того, чтобы повторно изобретать велосипед и интегрировать его в свое приложение, можно через Android обратиться к другим, специально заточенным под решение требуемой задачи приложениям. Например, если вам нужно выбрать контакт пользователя, то длинный путь состоит в обращении к базе данных телефона, выгрузке этих данных в ListView, реализации логики выбора контакта в ListView. Опытный разработчик вряд ли будет городить все это, а с помощью Intent обратиться к книге контактов Android. Существует огромное количество задач, которые могут быть решены с помощью интентов: получение картинок и видео с камеры, проигрывание видео, установка напоминаний и будильника и многое другое. Просто и красиво.
Неиспользование fragments
В стародавние времена, еще до Honeycomb, Android приложения строились только на базе активити и сервисов. Это доставляло массу неудобств при написании программ, которые должны были работать как при альбомной, так и при книжной ориентации устройства. Ночи, проведенные за отладкой и адаптацией макетов не редко заканчивались убитыми об стену устройствами, а ремонт планшетов и телефонов не самое дешевое дело. Внесение в API концепции фрагментов существенно улучшило ситуацию. Фрагмент — это мини активити, которая может быть встроена в обычную активити. Причем можно встроить в активити сразу несколько фрагментов. Это позволяет писать более элегантный код, отрабатывающий изменение ориентации устройства.
Разработка для текущей версии Android
Пожалуй самой обсуждаемой в среде программистов проблемой Android OS является ее фрагментация. На рынке одновременно присутствует большое количество устройств, работающих под различными версиями операционной системы. Каждая версия имеет собственный API. Начинающие разработчики очень часто ориентируются на последнюю версию операционной системы, отсекая тем самым огромный кусок рынка. Опытные программисты ориентируются на более старые версии и используют для обратной совместимости «Android Support Library». На самом деле, нет никакой реальной необходимости писать под очень старые устройства. Например, ориентация на Ice Cream Sandwich позволяет покрыть 95% находящихся на рынке устройств.
Разработка для одного или двух экранов
Фрагментация проявляется и в том, что при разработке приложений программист вынужден учитывать, что его приложение будет запускаться на устройствах с различным разрешением и размером экранов. Попыткой решения этой проблемы было привязывание всех размеров к dp и sp. Тем не менее, при написании Android приложения разработчик должен постоянно переключаться между различными типами экранов, чтобы удостовериться, что его программа нормально отображается. Новички обычно забывают про это и тестируют свой софт на одном-двух телефонах. Это неправильно.
Блокирование основного (UI) потока
При запуске любого приложения Android создает поток выполнения, называемый главным потоком или UI потоком. В этом потоке обрабатываются события щелчка по экрану, рисование и обновление экрана. По умолчанию весь код выполняется именно в этом потоке. Это может вызвать проблему — если у вас выполняется какая-нибудь долгая операция внутри UI потока, то приложение будет «подвисать». Особенно это актуально для приложений, взаимодействующих с сетью. В новых версиях Android работу с сетью запрещено осуществлять из основного потока, но остается целый ряд потенциально «тяжелых» задач, которые могут подвесить ваше приложение. Примером таких задач служат загрузка изображений, чтение/запись в файл или базу данных, сложные вычисления. Выходом может стать помещение этих задач в отдельные потоки. Приведенный ниже код иллюстрирует загрузку изображения и отображение ее в ImageView. Опытные разработчики никогда не позволяют своим приложениям подвисать. Если вам не знакома эта тема, рекомендую почитать об AsyncTask и использовании ProgressBar.
Пренебрежение документацией
Android Developer website — очень хороший ресурс, содержащий массу полезной информации для Android разработчиков. Документация, уроки, спецификации, обзор лучших решений — все это можно найти на Android Developer website. Если Вы всерьез собираетесь заняться программированием под Android — этот сайт должен быть у Вас в закладках. Начинающим разработчикам можно также рекомендовать StackOverflow — online сообщество, где можно задать вопрос и получить на него квалифицированный ответ. Начинающий программист с почти стопроцентной вероятностью найдет здесь ответ на мучающий его вопрос.
Глубокая иерархия в макетах экранов
При разработке макетов экранов своих программ (layouts) начинающие разработчики почему-то полагают, что использование базовых layout структур автоматически гарантирует создание эффективных и оптимизированных макетов. На самом деле, каждый виджет и layout, добавленный в приложение увеличивает время отрисовки экрана. В частности, использование параметра layout_weight — довольно дорогое в плане затрат времени удовольствие. Гораздо эффективнее использовать RelativeLayout и выстраивать виджеты по отношению друг к другу. С другой стороны, использование вложенных друг в друга layout-ов тоже очень накладно с точки зрения расхода времени.
Неправильное использование картинок
Графика является одним из самых больших кусков современных приложений. Прежде чем попасть на экран картинка должна быть загружена в память. Новички часто сталкиваются с OutOfMemoryError, когда пытаются загрузить коллекцию изображений. Например, загрузка картинки 2448×3264 ARGB_8888 потребует 4 * 2448 * 3264 байт памяти (около 30 Мб). Если вы потом собираетесь использовать эту картинку для отображения через ImageView размером 200×200, то на самом деле вам нужно всего 4*200*200 байт (около 160Кб). Довольно расточительно тратить 32Мб, когда действительно используется только 160Кб. При загрузке изображений опытные разработчики используют Bitmap.createScaledBitmap(). Кроме того, не стоит загружать картинки в основном потоке.
Мобильное приложение не маленький проект
Эту ошибку делают все, кто впервые сталкивается с мобильной разработкой. Новички считают мобильные приложения простыми программами, для написания которых хватит выходных. Это заблуждение очень далеко от реальности. Разработка android программ ничем не отличается от написания любого другого софта. Вам также понадобится разрабатывать спецификации, планировать свое время, наладить багтрекинг и серьезно готовиться к релизу.
Заключение
Разработка для Android очень увлекательное занятие (или тяжелая работа, кому как нравится). Рассмотренные ошибки это лишь небольшой список граблей, которые затаились в ожидании неопытного android разработчика. Наверняка вы тоже сталкивались с ошибками, не попавшими в этот список. Поделитесь опытом.
Источник