Методы лечения различных ошибок в 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).
Источник
No tasks available when executing JUnit runner class
I am trying to run Cucumber feature files in IntelliJ.
Cucumber Options is pointing to the right folder, but I get the «No tasks available» notification when trying to execute the JUnit runner class.
What am I doing wrong?
Here is my build.gradle :
Answers
Ok, none of the proposed solutions worked, but I finally figured it out.
Went to Settings > Build, Execution, Deployment > Build Tools > Gradle and changed Run tests using: from Gradle (Default) to IntelliJ IDEA .
Note: found the solution here.
ConfigurationManagerTest is not being found on your classpath. Ensure that the ConfigurationManagerTest.class file is available on your classpath.
It might not exist if it wasn’t successfully compiled or if it’s being created in a directory that you haven’t told the Eclipse project should be on the classpath.
Assuming that you’ve put your test classes in a separate folder, make sure that it shows up in the «Package Explorer» view (rather than the «Navigator» view).
Under the project properties, «Java Build Path» and the «Source» tab, you can also see if the source folder is included for building as well as where the .class files are generated.
OK it seems I’ll have to answer this question by myself.
The main reason for this problem is still the m2eclipse eclipse plug-in. The new version of this plugin does not support nested modules in one project. If we really need to see multiple modules we have to remove the old one from the package explorer and create a working set and import the project again using the option «import existing maven projects». The eclipse import wizard will pop up a window and ask you which module to be imported. Then we can select all the modules and finish the import. As a result the working set will contain all the modules of your project and treat each module as a separate project, although in the workspace your modules are still in one project. By doing this it resolves all the problems that I have come across in Eclipse related to classpath, such as not being able to search a class or not being able to run the unit tests and get a java.lang.ClassNotFoundException.
For reference, here is an article to teach you how to create a working set: Working set
I think you can import the project without creating a new working set but the working set will keep all the modules that belong to your project in one set so it is easier to organize.
I wish I had the answer two months ago so I wouldn’t have spent much time searching for a solution.
Источник
Background Task Inspector
Android Studio includes multiple inspectors, such as the Layout Inspector and Database Inspector, to help you investigate and understand the internal state of your running app. With Android Studio Arctic Fox, we are releasing a new inspector to help you monitor and debug workers your app schedules using WorkManager 2.5.0 or higher.
WorkManager is the recommended way to run asynchronous tasks in the background, even after the app is closed. Although it’s easy to configure your tasks as WorkManager workers, once a worker is queued, its execution is difficult to monitor and tricky to debug if you face issues.
With the Background Task Inspector, you can easily monitor the status of a worker, see its relationship with other chained workers, or inspect details, such as the worker output, frequency, and other timing information. Let’s see what the Background Task Inspector can do on a sample project.
To demo the Background Task Inspector, I’ll use the WorkManager sample app in architectural-components repo. If you want to give it a try, you can check out the repo and follow along as you read the article.
This app uses WorkManager to apply user selected filters on the selected photo. After running the app, users can choose a photo from the gallery or simply use a random stock photo. To see how the Background Task Inspector works, I run the app and select an image to apply some filters.
Each filter is implemented as a WorkManager worker. After a short wait, the app displays the photo with the selected filters applied. Without any further knowledge on the sample app, let’s see what else I can figure out by just using the Background Task Inspector.
To open the Background Task Inspector, select View > Tool Windows > App Inspection from the menu bar.
With the Background Task Inspector tab selected in the App Inspection window, I run the app again on a device or emulator running API level 26 or above. If it is not automatically selected, I choose the app process from the drop-down menu. After connecting to the app process, I can then go to my running app and select all filters and click apply. This time I can see a list of running jobs in the Background Task Inspector.
The Background Task Inspector lists the class name, current state, start time, retries and the output data of all the running/failed or completed jobs. Clicking on a specific job from the list opens the work details panel.
This panel provides more detailed information for each worker’s description, execution, work continuation and the results. Let’s take a close look at each section.
Description section lists the Worker class name with the fully qualified package, as well as the assigned tag and the UUID of this worker.
Next, the execution section shows the worker’s constraints (if any), running frequency, it’s state and which class created and queued this worker.
WorkContinuation section displays where this worker is in the work chain. You can check the previous or the next worker, if any, or the other jobs in the work chain. You can click to another Worker UUID to navigate and see the selected worker’s details. Looking at this work chain, I can see that the app uses 5 different workers. The number of workers may differ depending on the choice of filters by the user.
This is great but imagining the work chain is not always easy if you are not familiar with the app. Another great feature of Background Task Manager Inspector is the ability to display the work chain as a graph. To do that I click the ‘Show in graph’ link in the WorkContinuation section or switch to Graph View by clicking the ‘show Graph View’ button on top of the jobs list.
This graph view can help you to understand the order of the workers, the data which is passed between workers and the current state of each worker.
The last section in the Work Details panel is the Results pane. In this section you can see the start time, retry count and the output data of the selected worker.
Let’s say I want to test what happens when a worker stops. To do that, I’ll run the app again, select the worker, wait until it changes to running state and click the ‘Cancel Selected Work’ on the top left. Once I do that, the worker I selected and the remaining workers in the chain change their status to canceled.
Graph view becomes even more useful if your app includes complex chaining relationships, such as the one here. The graph allows you to quickly see relationships between a complex set of workers and monitor their progress.
If you want to try the Background Task Inspector with a more complex graph or make some WorkManager art, you can find the code here and add the DummyWorkers to the continuation object as seen here.
Background Task Inspector will be available with Android Studio Arctic Fox release but it is already available for you to try in the Arctic Fox Preview channel and soon will be in beta! If your app uses Work Manager, please give a try and let us know what you think or simply share your WorkManager art with us!
Источник
Tasks и Back Stack в Android
Итак. Каждое Android приложение, как минимум, состоит из фундаментальных объектов системы — Activity. Activity — это отдельный экран который имеет свою отдельную логику и UI. Количество Activity в приложении бывает разное, от одного до много. При переходах между различными Activity пользователь всегда может вернуться на предыдущую, закрытую Activity при нажатии кнопки back на устройстве. Подобная логика реализована с помощью стека (Activity Stack). Его организация «last in, first out» — т.е. последний вошел, первый вышел. При открытии новой Activity она становится вершиной, а предыдущая уходит в режим stop. Стек не может перемешиваться, он имеет возможность добавления на вершину новой Activity и удаление верхней текущей. Одна и та же Activity может находиться в стеке, сколько угодно раз.
Task — это набор Activity. Каждый таск содержит свой стек. В стандартной ситуации, каждое приложение имеет свой таск и свой стек. При сворачивании приложения, таск уходит в background, но не умирает. Он хранит весь свой стек и при очередном открытии приложения через менеджер или через launcher, существующий таск восстановится и продолжит свою работу.
Ниже покажу картинку, как работает стек.
Если продолжать нажимать кнопку back, то стек будет удалять Activity до того, пока не останется главная корневая. Если же на ней пользователь нажмет back, приложение закроется и таск умрет. Кстати, я говорил о том, что когда мы сворачиваем наше приложение и запускам например новое, то наш таск просто уходит в background и будет ждать момента, пока мы его вызовем. На самом деле есть одно «но». Если мы будем иметь много задач в background или же просто сильно нагружать свое устройство, не мала вероятность того, что таск умрет из за нехватки системных ресурсов. Это не война конечно, но то что мы потеряем все наши текущие данные и наш стек очистится — это точно. Кстати для избежания потери данных в таком случаи, вам стоит почитать про SavingActivityState.
Маленький итог
Управление тасками
Существует два пути для изменения стандартной организации тасков. Мы можем устанавливать специальные атрибуты в манифесте для каждой Activity. Также мы можем устанавливать специальные флаги для Intent, который запускает новую Activity с помощью startActivity(). Заметьте, что иногда атрибуты в манифесте и флаги в Intent могут противоречить друг другу. В этом случаи флаги Intent будут более приоритетны.
Атрибут launchMode
Для каждой Activity в манифесте можно указать атрибут launchMode. Он имеет несколько значений:
- standard — (по умолчанию) при запуске Activity создается новый экземпляр в стеке. Activity может размещаться в стеке несколько раз
- singleTop — Activity может распологаться в стеке несколько раз. Новая запись в стеке создается только в том случаи, если данная Activity не расположена в вершине стека. Если она на данный момент является вершиной, то у нее сработает onNewIntent() метод, но она не будет пересоздана
- singleTask — создает новый таск и устанавливает Activity корнeвой для него, но только в случаи, если экземпляра данной Activity нет ни в одном другом таске. Если Activity уже расположена в каком либо таске, то откроется именно тот экземпляр и вызовется метод onNewIntent(). Она в свое время становится главной, и все верхние экземпляры удаляются, если они есть. Только один экземпляр такой Activity может существовать
- singleInstance — тоже что и singleTask, но для данной Activity всегда будет создаваться отдельный таск и она будет в ней корневой. Данный флаг указывает, что Activity будет одним и единственным членом своего таска
На самом деле не важно, в каком таске открыта новая Activity. При нажатии кнопки back мы все равно вернемся на предыдущий таск и предыдущие Activity. Единственный момент, который нужно учитывать — это параметр singleTask. Если при открытии такой Activity мы достанем ее из другого background таска, то мы полностью переключаемся на него и на его стек. на картинке ниже это продемонстрировано.
Флаги
Как и говорил, мы можем устанавливать специальный флаги для Intent, который запускает новую Activity. Флаги более приоритетны, чем launchMode. Существует несколько флагов:
- FLAG_ACTIVITY_NEW_TASK — запускает Activity в новом таске. Если уже существует таск с экземпляром данной Activity, то этот таск становится активным, и срабатываем метод onNewIntent().
Флаг аналогичен параметру singleTop описанному выше - FLAG_ACTIVITY_SINGLE_TOP — если Activity запускает сама себя, т.е. она находится в вершине стека, то вместо создания нового экземпляра в стеке вызывается метод onNewIntent().
Флаг аналогичен параметру singleTop описанному выше - FLAG_ACTIVITY_CLEAR_TOP — если экземпляр данной Activity уже существует в стеке данного таска, то все Activity, находящиеся поверх нее разрушаются и этот экземпляр становится вершиной стека. Также вызовется onNewIntent()
Affinity
Стандартно все Activity нашего приложения работают в одном таске. По желанию мы можем изменять такое поведение и указывать, чтобы в одном приложении Activity работали в разных тасках, или Activity разных приложений работали в одном. Для этого мы можем в манифесте для каждой Activity указывать название таска параметром taskAffinity. Это строковое значение, которое не должно совпадать с названием package, т.к. стандартный таск приложения называется именно как наш пакет. В общем случаи данный параметр указывает, что Activity будет гарантированно открываться в своём отдельном таске. Данный параметр актуален, если мы указываем флаг FLAG_ACTIVITY_NEW_TASK или устанавливаем для Activity атрибут allowTaskReparenting=«true». Этот атрибут указывает, что Activity может перемещаться между тасками, который её запустил и таском, который указан в taskAffinity, если один из них становится активным.
Чистка стека
Если таск долгое время находится в background, то система сама чистит его стек, оставляя только корневую Activity. Данное поведение обусловлено тем, что пользователь может забыть, что он делал в приложении до этого и скорее всего зашел в него снова уже с другой целью. Данная логика также может быть изменена с помощью нескольких атрибутов в манифесте.
- alwaysRetainTaskState — если флаг установлен в true для корневой Activity, то стек не будет чиститься и полностью восстановится даже после длительного времени
- clearTaskOnLaunch — если установить флаг в true для корневой Activity, то стек будет чиститься моментально, как только пользователь покинет таск. Полная противоположность alwaysRetainTaskState
- finishOnTaskLaunch — работает аналогично clearTaskOnLaunch, но может устанавливаться на любую Activity и удалять из стека именно её
Это всё для данного топика. Статья не импровизированная, а по сути является вольным переводом официальной документации. Рекомендую собрать легкий пример и поэксперементировать с флагами и атрибутами. Некоторые моменты, лично для меня были, неожиданно интересными. любые ошибки и недоработки учту в лс. Спасибо.
Источник