Редактор кода
Рассмотрим возможности редактора кода при написании приложений.
Инъекция языка
Студия позволяет делать инъекцию в существующий код. Что это такое? Например, JSON имеет свой формат данных. Если писать код вручную в данном формате, то можно столкнуться с неудобствами — вам приходится экранировать символы в большом фрагменте кода. Студия поможет нам. Создадим переменную jsonString:
Помещаем курсор между кавычками и нажимаем комбинацию Alt + Enter , выбираем пункт Inject language or reference, в выпадающем списке выбираем JSON (JSON files).

Далее следует ещё раз нажать комбинацию Alt + Enter , чтобы инъекция была постоянной. Студия добавит комментарий к переменной.
Если вы скопируете текст в формате JSON и вставите его между кавычками, то экранирование произойдёт автоматически.
Сам текст не обязательно копировать из другого источника, можете создавать JSON-запись в самой студии. Снова нажимаем Alt + Enter и выбираем пункт Edit JSON Fragment. Появится новая панель, в котором вы можете набирать текст, а в редакторе кода будет выводиться валидный код для работы.

Аналогично можно работать с регулярным выражением.

Перемещаем метод вверх или вниз
Иногда хочется для лучшей читаемости поменять местами методы в коде. Вырезать и вставлять в новое место слишком утомительно. Есть способ лучше. Установите указатель мыши на имени метода и нажмите комбинацию Ctrl+Shift+Стрелка_Вверх — метод автоматически перепрыгнет через метод над собой. Как переместить вниз вы сами догадаетесь.
Сворачиваем фрагменты кода
Студия умеет сворачивать фрагменты кода, которые являются структурной единицей, например, метод. Щёлкнув по фиговине (как это называется?), вы убираете код, чтобы не мозолил вам глаза.

Но мало кто знает, что свернуть можно любой свой код. Для этого ставим два слеша, как в комментариях, а затем добавляем слово region (без пробела) и через пробел название блока. Это будет началом блока. Конец блока обозначаем через //endregion
Теперь отмеченный блок можно сворачивать. Наведите порядок у себя в коде.


Редактор кода для XML в режиме Text
[I18N] Hardcoded string
Когда вы редактируете код разметки экрана активности, то можете встретить предупреждение [I18N] Hardcoded string «Какой-то ваш текст», should use @string resource.
![[I18N] Hardcoded string](https://developer.alexanderklimov.ru/android/studio/code_editor1.png)
Студия информирует вас о возможной проблеме, если вы в будущем задумаетесь о локализации приложения. Странное выражение I18N переводится очень просто. Здесь зашифровано слово INTERNATIONALIZATION — первая буква I, последняя буква N и восемнадцать букв между ними.
Вам нужно заменить свой жёстко закодированный текст на строковый ресурс. Установите курсор внутри текста, нажмите комбинацию клавиш Alt+Enter и выберите пункт Extract string resource. Далее в диалоговом окне придумываете имя для ресурса и выбираете файл для хранения (обычно, strings.xml).
Предположим, вы заменили везде текст на строковые ресурсы и решили отредактировать текст у кнопки. Снова ставим курсор на нужном тексте и нажимаем комбинацию клавиш Ctrl+B, у вас сразу откроется файл strings.xml и не надо его искать в дереве проекта.
Ещё один приём — если вы хотите видеть вместо кода android:text=»@string/click» реальный текст из ресурса, то нажмите комбинацию Ctrl+- (клавиша минус на цифровой клавиатуре) и он подтянется.
Вкладки
Каждый файл проекта открывается в собственной вкладке. Вкладки можно менять местами перетаскиванием с помощью мыши. Переключаться можно через клавиши Alt-стрелка влево и Alt-стрелка вправо. Также можно вызвать Switcher с помощью комбинации Ctrl+Tab.
Если будет открыто слишком много вкладок, то часть из них сгруппируется и будет доступна через выпадающий список по нажатию на треугольник.
Если имя файла на вкладке подчёркнуто красной волнистой линией, значит в коде содержится ошибка и не нужно запускать программы, то время потеряете. Сначала исправьте ошибку.

Вкладку можно «отстегнуть». Нажмите на вкладку и удерживая мышку, перетащите вкладку на рабочий стол. Также её можно вернуть обратно.
Каждая вкладка имеет контекстное меню и значок для закрытия. Изучите пункты меню самостоятельно. Например, можно разбить редактор кода на две части (по вертикали или горизонтали), чтобы видеть разные участки кода одновременно.
Строка состояния
В нижней части студии находится строка состояния. В нижнем правом углу имеется текстовая метка с информацией о текущем местоположении курсора в документе (номер строки:номер символа). Если подвести мышку к надписи, то можно увидеть всплывающую подсказку Click to go to line. Щелчок вызовет диалоговое окно для быстрого перехода на нужную позицию.
Рядом также имеется текстовая метка с указанием кодировки, в которой пишется код. В последних версиях студии это стало проблемой для русскоязычных программистов. Студия может использовать системную кодировку, которая часто бывает windows-1551, но в Android принято использовать UTF-8, и после запуска приложения вместо текста можно увидеть кракозябры.
Остальные элементы не представляют интереса.
Информационный желоб
Слева от редактора кода имеется отдельная полоска, которую я назвал информационным желобом. На ней можно увидеть различные значки. Например, у класса MainActivity выводится значок, связанный XML-разметкой для данного класса. Нажав на него, вы можете быстро открыть нужный XML-файл.
Также выводятся значки для методов. Каждый тип методов имеет свой цвет.
В данном желобе устанавливаются точки останова (breakpoint).
Доступно контекстное меню. Например, можно выбрать показ номеров строки.
На границе желоба и редактора кода имеются маркеры для сворачивания блоков кода.
Если нажать клавишу F11, то текущая строка будет помечена как закладка и появится галочка.
Анализ кода
Справа от редактора кода находится анализатор кода. Если код содержит ошибки, сверху будет гореть красный прямоугольник. Если ошибок нет, но есть предупреждения, то будет гореть жёлтый прямоугольник. При правильном коде горит зелёный прямоугольник.
В случае ошибок или предупреждений также выводятся зарубки. Если подвести к ним курсор мыши, то можно прочитать сообщение или сразу перейти в нужную строку для исправления, нажав на неё. Также есть синие зарубки для выделенных слов и задач TODO.

Автодополнение кода
Студия поддерживает автодополнение кода, когда по первым символам подставляет нужные слова. Распространяться на эту тему не буду.
Основная комбинация Ctrl+Space.
Если написать имя метода, например, «private void onClick()» и нажать комбинацию Ctrl+Shift+Enter, то студия сгенерирует фигурные скобки.
Когда у вас есть кусок кода и вы начинаете исправлять его, то возникает следующая ситуация. Студия предлагает подсказку, вы соглашаетесь и нажимаете Enter.

В данном случае мы хотим заменить переменную name на catName, но если нажмём на Enter, то подсказка присоединится к старому коду и мы получим catNamename. В следующий раз нажимайте на клавишу Tab и тогда старый вариант заменится на новый.
Также изучите другие клавиатурные комбинации.
Периодически используйте команды меню Code: Reformat Code и Rearrange Code. Первая команда полезна для Java-кода, а вторая для XML-разметки. Код станет аккуратнее.
Перевод на новую строку
Если курсор находится в середине выражения и вы хотите начать новую строку, не обязательно гнать курсор в конец строки. Просто нажмите комбинацию Shift+Enter.
8 things you probably didn’t know you could do in Android Studio
There are multiple ways to approach Android Development, but by far the most official and powerful is to use Android Studio. It is the official IDE (Integrated Development Environment) for the Android platform, developed by Google and used to make the majority of the apps that you probably use today.
Over the years it’s capabilities has increased proportionally with the release of every new version. In this article i’ll highlight about eight things you may or may not already know that your studio can do. We’ll also explain how to do them and and show pictures where necessary. In the end, it’ll help you understand your studio better, increase productivity and lower development time.
1. Manage Clipboard
Did you know that Android Studio allows you to manage the contents of your clipboard ?.
During development, we copy and cut a lot of code snippets as we move codes around the studio from one method to the other and so on. By default, we can only paste the last item we copied, however, Android Studio lets you decide which of all your copied items you wish to paste. The depth of the clipboard is five by default so you can only see the last five items you copied, however you can still extend the depth to any length of your choice if you so wish.
How to manage the clipboard —
To show a list of all your copied items in Android Studio, press Ctrl +Shift + V for Windows or Linux and press Cmd + Shift+ V on Mac. It’ll pop up a list of your last five copied items where you can select which one you want to paste
2. Modify logcat display
Did you know that you can customize your logcat to display messages in different colors for different log categories ?.
Finding a particular log message can get very daunting given that there are tons and tons of log messages to scroll through. By default, we simply search for what we are looking for. However, it’s not always as effective as we’d probably like. Android Studio now allows us tocustomize colors for different log message categories, hence making it easier and less complicating to work with the logcat.
How to customize the logcat colors —
Click on File >> Settings >> Colors & Fonts >> Android Logcat :
Here are the colors i used on the image above
- VERBOSE — #BBBBBB
- DEBUG — #7794BB
- INFO — #4FBB1A
- WARN — #BBB60D
- ERROR — #FF0C11
- ASSERT — #FF4081
3. Create String resources from hardcoded Strings
Did you know that you can hardcode Strings in your studio and create them as resources with just keyboard commands ?.
While typing codes, most developers like me don’t always go to resources to define Strings first lol. If you’re equally guilty of this, Android will highlight all the hardcoded strings and prompt you to add them as resources. This can make your code look untidy and moving all the strings to resources? Well, it’s tiring especially when there are hundreds of them.
But the good news is, you can migrate them to resources directly from the file where you defined them with just a keyboard command.
How to create string resources from hardcoded strings —
On windows, ensure that the caret is on the text you want to move to resources then press alt + Enter just as though you want to import a class. On Mac it is option + return :
4. Persist logcat data when the app crashes
Did you know that you can keep the data of your current app in the logcat even after it crashes?
One thing we cannot avoid while building an Android application is running into errors and app crashes. Most times when it happens, we lose valuable information about the current session. Luckily for us, there is a way to avoid this mess, but not many people know.
How to persist logcat data —
Open Logcat and navigate to the show only selected application menu and click the dropdown. From the dropdown menu, select Edit filter configuration. This will pop up a menu where you’ll type in a filter name and your application package name. Click Ok when you’re done.
5. Multicursor selection
Did you know that you can select multiple texts in Android Studio and act on them all at once ?.
Being able to effect changes on two or more exact words and change, update or delete them on the fly is a very handy feature for any software developer. Android Studio allows us to do this in a very seamless manner.
How to select and effect multiple texts —
On windows, simply highlight one instance of the desired text that you’d like to effect changes on and press alt + j on Mac, press control + g then start typing the changes you want to make
6. Live templates
Did you know that you can access live code templates in Android Studio, you can use postFix code completion to transform an already typed expression into another one. ?
One of the most productive way to speed up development time is using live templates and postFix code completion. It is a very handy feature that generates a bunch of code snippets depending on your context. Live Templates let you use shortcuts that are available as autocompletion options that will insert templatized snippets into your code.
How to implement live templates —
Lets take for example you want to surround a piece of code with callable. You can either start typing the entire code word by word, or you can simply press Ctrl + j on windows or Cmd + j on Mac to pop up a list of the available code templates in that context. From there, you can select surround with callable and it’ll implement the code for you
7. postFix code completion —
While live templates allow us to insert some of the most common code patterns into our work with quick shortcuts, we can use postfix code completion to transform an already typed expression into another one. This is very handy when we are dealing with repetitive codes like for-loops, if-else statements and so on.
8. Move between design and text tabs
Did you know that you can switch tabs in between Design and Text in layout view?
While in active development, we occasionally navigate between the design and text tabs for a lot of developmental reasons. Most times, this requires that we mouse through these tabs every single time we need to make a switch. Again, we can use a keyboard shortcut for this.
On windows, simply press alt + shift + ←/ →
On Mac, it is control shift + ←/ →
Resources
Conclusion
Hi guys, apologies I haven’t written in a while, i got really busy with work. But hey.. i can’t stop writing.
So I’ve written this article to expose a few tricks that has been helping me over the time that i’ve been away hoping that it’d help you too. If you’ve learnt something new from the article, feel free to clap as many times as you can so someone else who needs it can find it.
Feel free to leave comments on the awesome things you’re doing in Android Studio that we might have not found out yet, suggest more topics you’d like me to write about, follow me on Twitter and reach out when you want to.
Русские Блоги
Инструменты Android Studio: инструмент сканирования кода Lint (включая пользовательский Lint)
Что такое Линт
Android Lint — это инструмент сканирования кода, представленный SDK Tools 16. (ADT 16). Благодаря статическому анализу кода он может помочь разработчикам найти проблемы с качеством кода и предложить некоторые предложения по улучшению. Помимо проверки на возможные ошибки в исходном коде проекта Android, будут также проверяться правильность, безопасность, производительность, простота использования, удобство и интернационализация кода.
Android Lint используется в качестве инструмента обнаружения кода для проекта, поскольку он имеет следующие характеристики:
- Был интегрирован в Android Studio, прост в использовании.
- Может написать потенциальные проблемы в режиме реального времени при написании кода.
- Правила могут быть настроены. Сам Android Lint содержит большое количество инкапсулированных интерфейсов, которые могут предоставлять богатую информацию о коде, и разработчики могут писать собственные правила на основе этой информации.
Сначала придет фигура бога

Специальная информация после lint.png
1. Начните
Рабочий процесс Android Lint относительно прост: базовый процесс Lint состоит из трех частей: Lint Tool (инструмент обнаружения), Source Files (исходный файл проекта) и lint.xml (файл конфигурации). Lint Tool читает Source Files, согласно lint .xml правила конфигурации (выдачи) результатов вывода (как показано ниже).

1.1 Использование студии Android
В Android Studio Android Lint был интегрирован, просто нажмите меню-Анализ-Проверить код, чтобы запустить Android Lint, во всплывающем диалоговом окне вы можете указать объем выполнения Lint, вы можете выбрать весь проект или вы можете просто выбрать текущий Подмодули или другие пользовательские области:

После завершения проверки откроется консоль проверки и отобразятся подробные результаты проверки:

Как показано на рисунке выше, Android Lint классифицирует результаты проверки. Проблемы по тому же правилу (проблема) будут агрегированы. Категории правил для Android будут объяснены до того, как классификация связана с Android, в основном в шести категориях:
- ДоступностьТакие как ImageView отсутствие описания contentDescription, строка кодирования строки и другие проблемы.
- корректность корректность
- Интернационализация ИнтернационализацияТакие, как отсутствие перевода символов.
- Производительность ПроизводительностьНапример, new выполняется в onMeasure и onDraw, происходит утечка памяти, генерируются избыточные ресурсы, а структура xml является избыточной.
- Безопасность БезопасностьНапример, не использовать HTTPS для подключения к Gradle, проблемы с разрешениями в AndroidManifest и т. Д.
- Юзабилити простота использования, Таких как отсутствие определенных многократных сокращений, повторных значков и т. Д.
Другие записи результатовДля синтаксиса JavaПроблема, и каждая проблема имеет серьезность (серьезность), снизу вверх:
Fatal
Error
Warning
Information
Ignore
Где Fatal и Error относятся к ошибкам, но ошибки типа Fatal напрямую прерывают ADT export APK, что более серьезно.
Нажмите на запись в списке результатов, вы увидите подробное имя и местоположение исходного файла, а также правила ошибки попадания (проблема), решения или советы по блокировке.
Помимо запуска Lint непосредственно в меню, Android Studio будет напоминать при написании большей части кода проблемы:
1.2 Конфигурация
Соответствующая конфигурация для выполнения операций Lint определена в lintOptions файла gradle, определяемых параметрах и их значениях по умолчанию
lint.xmlЭтот файл предназначен для настройки правил, которые Lint необходимо отключить (выдать), и серьезности пользовательских правил (серьезность). Файл lint.xml передаетсятег выпускаУкажите контроль над правилом, приКорневой каталог проектаПосле создания файла lint.xml вAndroid Lint автоматически распознает файлИ проверьте содержимое файла lint.xml при выполнении проверки. Как упоминалось выше, разработчики также могут указывать файлы конфигурации с помощью параметра lintConfig в lintOptions. Пример lint.xml выглядит следующим образом:

Используется в теге проблемыid определяет правило, Severity = "ignore" указывает, что это правило отключено. Следует отметить, что некоторые правила могут быть указаны для отключения только для определенных атрибутов с помощью тега игнорирования, такого как вышеупомянутый Устаревший, что означает проверку использования рекомендованных атрибутов и методов и перенос тега игнорирования в тег выпуска и тег игнорирования Одиночное выражение указывается в атрибуте regexp с помощью регулярного выражения, указывающего, что атрибут singleLine защищен от проверки.
Кроме того, разработчики могут также использовать аннотацию @SuppressLint (идентификатор проблемы), чтобы игнорировать определенные проверки Lint для определенных кодов.Эту аннотацию можно добавить перед переменными-членами или перед объявлениями методов и объявлениями классов, соответственно, для маскировки различных диапазонов ,
Во-вторых, расширить рассказ
2.2.1 Правильность (не все, общие)
Appcompat Custom Widgets
Пользовательские виджеты Appcompat обычно позволяют вам наследовать от android.support.v7.widget.AppCompat .
Не расширяйте непосредственно класс android.widget, а скорее расширяйте класс делегата в android.support.v7.widget.AppCompat.
Attribute unused on older versions
Неиспользуемый атрибут старой версии имеет minSdkVersion
Это не ошибка, приложение просто игнорирует этот атрибут.
Вы можете создать копию макета в папке layout-vNN. Она будет использоваться в API NN или более поздней версии, а также вы сможете воспользоваться обновленными атрибутами.
Class is not registered in the manifest
Класс не зарегистрирован в списке
Activities, services and content providers should be registered in the AndroidManifest.xml file
Combining Ellipsize and Maxlines
Сочетание размеров эллипса и макслайнов
Сочетание ellipsize и maxLines = 1 может привести к сбою некоторых устройств. В более ранних версиях lint предлагалось заменить singleLine = true на maxLines = 1, но этого не следует делать при использовании ellipsize
Extraneous text in resource files
посторонний текст в файле ресурсов
Hardcoded reference to /sdcard
Жестко закодированная ссылка / SD-карта
Код не должен напрямую ссылаться на путь / sdcard; вместо этого используйте: Environment.getExternalStorageDirectory (). getPath ()
Не указывайте напрямую / data / data / path, он может отличаться в многопользовательских сценариях.
Implied default locale in case conversion
локаль по умолчанию в случае конвертации
Implied locale in date format
Неявная локаль формата даты
Операторы вызова должны использовать getDateInstance (), getDateTimeInstance () или getTimeInstance (), чтобы получить готовый экземпляр SimpleDateFormat, подходящий для локали пользователя.
Likely cut & paste mistakes
Возможные ошибки вырезания и вставки
Вырезайте и вставляйте вызов findViewById, но не забудьте обновить поле R.id. Возможно, ваш код просто (избыточен) постоянно ищет поля
Mismatched Styleable/Custom View Name
Несоответствующий стиль / имя пользовательского представления
Соглашение о настраиваемом представлении заключается в использовании стиля объявления, имя которого совпадает с именем класса настраиваемого представления.
Missing Permissions
Отсутствуют разрешения
Nested scrolling widgets
Вложенный виджет прокрутки
A scrolling widget such as a ScrollView should not contain any nested scrolling widgets since this has various usability issues
Obsolete Gradle DependencyУстаревшие зависимости Gradle
Target SDK attribute is not targeting latest versionАтрибут target SDK не ориентирован на последнюю версию
Using ‘px’ dimensionИспользовать измерение "px"
Using android.media.ExifInterfaceИспользуйте android.media.ExifInterface
Старая версия имеет некоторые уязвимости, используя
Using dp instead of sp for text sizesИспользуйте dp вместо размера текста sp
Using Private APIsИспользовать приватный API
Using private resourcesИспользование частных ресурсов
2.2.2Internationalization
Hardcoded text
жестко закодированный текст
Он имеет недостатки в жестком кодировании текстовых атрибутов непосредственно в файле макета
should use @string resource
Overlapping items in RelativeLayout
перекрывающиеся элементы в RelativeLayout
Если элементы текста или кнопки относительного макета выровнены по левому и правому краям, они могут перекрывать друг друга из-за расширения локализованного текста, если у них нет взаимных ограничений, таких как toEndOf / toStartOf.
Padding and margin symmetry
Заполнение и симметрия ребер
Если вы укажете отступы или поля на левой стороне макета, вы также сможете указать отступы на правой стороне (и наоборот), чтобы макет был симметричным справа налево.
TextView Internationalization
Интернационализация TextView
Никогда не вызывайте Number # toString () для форматирования чисел, он не будет правильно обрабатывать дробные разделители и специфичные для региона числа
Используйте формат String # с правильной спецификацией формата (% d или% f)
Не передавайте строку (например, «Hello») для отображения текста. Жестко закодированный текст не может быть правильно переведен на другие языки, рассмотрите возможность использования строк ресурсов Android
Не создавайте сообщение, соединяя текстовые блоки. Такие сообщения не могут быть переведены правильно.
Using left/right instead of start/end attributes
Используйте левый / правый вместо начального / конечного атрибутов
2.2.3Performance
- Handler reference leaks
Утечка, вызванная обработчиком
Поскольку обработчик объявлен как внутренний класс, он может предотвратить сборку внешнего класса. Если обработчик использует Looper или MessageQueue для потоков, отличных от основного потока, проблем не возникает. Если обработчик использует Looper или MessageQueue основного потока, вам нужно исправить оператор Handler,
Решение: объявите обработчик как статический класс; во внешнем классе создайте экземпляр WeakReference для внешнего класса и передайте этот объект обработчику при создании экземпляра обработчика; используйте объект WeakReference для ссылки на внешний класс Все участники класса.
HashMap can be replaced with SparseArray
HashMap можно заменить на SparseArray
Для отображений, у которых тип ключа целочисленный, использование API-интерфейса Android SparseArray обычно более эффективно.
Inefficient layout weight
Неэффективные веса макета
Когда только один элемент управления в LinearLayout определяет вес, более эффективно назначить ему ширину / высоту 0dp, поскольку он будет поглощать все оставшееся пространство. Если заявленная ширина / высота равна 0dp, нет необходимости сначала измерять его собственный размер.
Layout has too many views
Слишком много мнений о макете
Использование слишком большого количества представлений в одном макете ухудшает производительность. Подумайте об использовании составного чертежа или других методов, чтобы уменьшить количество видов в этом макете. Максимальное количество просмотров по умолчанию равно 80, но его можно настроить с помощью переменной среды ANDROID_LINT_MAX_VIEW_COUNT.
Layout hierarchy is too deep
Уровень макета слишком глубокий
Вложение слишком большого количества макетов ухудшает производительность. Попробуйте использовать более плоский макет (например, RelativeLayout или GridLayout). Максимальная глубина по умолчанию — 10, но ее можно настроить с помощью переменной среды ANDROID_LINT_MAX_DEPTH.
Memory allocations within drawing code
Память выделяется в коде чертежа
Следует избегать назначения объектов во время операций рисования или макета. Они вызываются часто, поэтому плавный пользовательский интерфейс может прерываться паузами сбора мусора, вызванными выделением объектов. Обычный подход заключается в том, чтобы предварительно выделить необходимые объекты и повторно использовать их для каждой операции рисования. Некоторые методы выделяют память от вашего имени (например, Bitmap.create), и эти воспоминания должны обрабатываться таким же образом.
Missing @Keep for Animated Properties
Отсутствует анимация атрибута @Keep
Когда вы используете аниматор свойств, доступ к свойствам можно получить через отражение. Эти методы должны быть аннотированы @Keep, чтобы гарантировать, что во время сборки релиза эти методы не будут считаться неиспользованными и удаленными, или считаться внутренними, и переименованы, чтобы быть короче. Эта проверка также помечает другие возможные проблемы отражения, такие как отсутствующие атрибуты, неправильные типы параметров и т. Д.
Missing baselineAligned attribute
Атрибут baselineAligned отсутствует
При использовании LinearLayout для пропорционального распределения пространства между вложенными макетами свойство выравнивания базовой линии должно быть отключено, чтобы ускорить расчет макета.
Node can be replaced by a TextView with compound drawables
Узел может быть заменен составным отображаемым TextView.
LinearLayout, содержащий ImageView и TextView, может быть более эффективно обработан как составное рисование (один TextView, используйте атрибуты drawableTop, drawableLeft, drawableRight и / или drawableBottom для рисования одного или нескольких изображений рядом с текстом) , Если два виджета имеют пустое пространство между собой, их можно заменить свойством drawablePadding.
Obsolete layout params
Устаревшие параметры макета
Obsolete SDK_INT Version Check
Проверка устаревшей версии SDK_INT
Эта проверка версии галочки не обязательна, поскольку minSdkVersion (или известный уровень API) по крайней мере так же высок, как проверенная версия.
Он также будет искать ресурсы в папке -vNN, такие как values-v14, спецификатор версии которого меньше или равен minSdkVersion, где содержимое должно быть объединено в лучшую папку.
Static Field Leaks
Статические константы — содержат ссылки на фрагмент и действие
Нестатические внутренние классы имеют неявные ссылки на свои внешние классы.
Если внешний класс представляет собой, например, фрагмент или действие, если долго выполняющийся обработчик / загрузчик / задача будет содержать ссылку на действие, он не был переработан в течение длительного времени.
Useless parent layout
Бесполезный родительский макет
Макет с дочерними элементами без братьев и сестер не является представлением прокрутки или корневым макетом и не имеет фона, его можно удалить, а его дочерние узлы перемещаются непосредственно в родительский узел для более плоской и более эффективной компоновки Слоистая структура.
View Holder Candidates
Просмотр кандидатов в держатели
Should use View Holder pattern
2.2.4Security
Cipher.getInstance with ECB
Cipher.getInstance и ECB
Вы не должны использовать ECB в качестве режима шифрования или вызывать Cipher # getInstance без установки режима шифрования, поскольку режимом по умолчанию для Android является ECB, что небезопасно. (Шифрование и дешифрование)
Content provider does not require permission
Поставщик контента не нуждается в разрешении
Поставщики контента экспортируются по умолчанию, и любое приложение в системе может использовать их для чтения и записи данных. Если поставщик содержимого предоставляет доступ к конфиденциальным данным, его следует защитить, указав в манифесте значение export = false или предоставив разрешения другим приложениям.
Exported service does not require permission
Экспортированная служба не требует разрешения
Экспортируемые сервисы (сервисы с exported = true или intent-filter не указаны и exported = false) должны определять разрешения, которые должен иметь объект для запуска сервиса или связывания с сервисом. , Без этого любое приложение может использовать этот сервис.
Hardware Id Usage
Использование идентификатора оборудования
Эти идентификаторы устройств не рекомендуются, за исключением предотвращения мошенничества с высокими ценностями и расширенного использования телефона.
getLine1Number получить номер телефона, IMEI устройства getDeviceId, адрес getMacAddressMAC
Incorrect constant
Неверная константа
Insecure TLS/SSL trust manager
Небезопасный менеджер доверия TLS / SSL
Missing @JavascriptInterface on methods
Метод @JavascriptInterface отсутствует
openFileOutput() or similar call passing MODE_WORLD_READABLE
openFileOutput () или аналогичные вызовы проходят MODE_WORLD_READABLE
openFileOutput() or similar call passing MODE_WORLD_WRITEABLE
openFileOutput () или аналогичные вызовы проходят MODE_WORLD_WRITEABLE
В некоторых случаях приложения могут записывать файлы, доступные для записи, но эти файлы следует тщательно проверять, чтобы убедиться, что они не содержат личных данных, и если файл был изменен вредоносным приложением, Будет обманывать или уничтожать приложение.
Receiver does not require permission
Получателю не нужно разрешение
Using setJavaScriptEnabledИспользуйте setJavaScriptEnabled
Если вы не уверены, что вашему приложению требуется поддержка JavaScript, тогда ваш код не должен вызывать setJavaScriptEnabled.
2.2.6Usability
- Button should be borderless
Кнопка должна быть без полей
Две кнопки, размещенные в макете, будут оцениваться как панель кнопок, вам нужно добавить стиль для отмены ее границы
Добавьте атрибут style = "? android: attr / buttonBarButtonStyle" на кнопках. Системная подсказка также может добавить атрибут style = "? Android: attr / buttonBarStyle" в родительский макет кнопки.
Ellipsis string can be replaced with ellipsis character
Строка с многоточием может быть заменена символом с многоточием
Replace ". " with ellipsis character (…, …) ?
Hyphen can be replaced with dash
Дефисы можно заменить тире
Replace "-" with an "en dash" character (–, –) ?
Missing View constructors for XML inflation
Отсутствует конструктор представления для инфляции XML
Text size is too small
Текст слишком маленький
Избегайте использования размеров меньше 12sp. Шрифты меньше 12sp будут слишком маленькими, чтобы их было ясно видно пользователям
2.2 Другие типы
Class structureКлассовая структура
Code maturity issuesВопросы зрелости кода
Code style issuesПроблемы со стилем кода
Compiler issuesПроблемы с компилятором
Control flow issuesПроблема управления потоком
Data flow issuesПроблема потока данных
Declaration redundancyИзбыточность заявления
Error handlingОбработка ошибок
GeneralВ общем
Importsимпорт
J2ME issuesПроблемы с J2ME
Java 5 Java 5
Java 7 Java 7
Java language level migration aids JavaПомощь в миграции на уровне языка
Javadoc issues JavadocПроблема
Naming conventionsСоглашение об именах
Numeric issuesЦифровые проблемы
Performance issuesПроблемы с производительностью
Probable bugsВозможные ошибки
Properties FilesФайл свойств
Spellingорфография
Styleстиль
Verbose or redundant code constructsПодробная или избыточная структура кода
XML XML
2.2.1Class structure
Поле может быть локальным
Параметр может быть локальным
‘private’ method declared ‘final’
‘static’ method declared ‘final»
2.2.2 Вопросы зрелости кода
Устаревшее использование API не рекомендуется
Устаревший член все еще используется
2.2.3 Проблемы со стилем кода
Ненужный модификатор enum Ненужный модификатор enum
Ненужный модификатор интерфейса Ненужный модификатор интерфейса
Ненужная точка с запятой Ненужная точка с запятой
private public
2.2.4 Проблемы с компилятором
2.2.5 Проблемы управления потоком
Двойное отрицание
Бессмысленное логическое выражение
Избыточный оператор if Если избыточный оператор if
Избыточное условное выражение
Упрощаемое логическое выражение
Упрощаемое условное выражение
Ненужный оператор ‘return’ ненужный оператор ‘return’
return;
2.2.6 Проблемы с потоком данных
Булев метод всегда инвертирован
Избыточная локальная переменная
2.2.7 Декларация избыточности
Доступ к статическому члену через ссылку на экземпляр
this.minsize = this.maxsize;
Фактический параметр метода — та же константа
Actual value of parameter »register» is always »true»
Доступ к декларации может быть слабее
Can be private
Декларация может иметь финальный модификатор
Метод может быть недействительным
Метод возвращает то же значение
All implementations of this method always return ‘3’
Пункт об избыточных бросках
The declared exception ‘UnsupportedEncodingException’ is never thrown
Ненужная зависимость от модуля
Неиспользуемое объявление Неиспользуемое объявление (метод, переменная)
2.2.8 Обработка ошибок
Пойманное исключение немедленно переброшено Пойманное исключение немедленно переброшено
Пустой блок ‘catch’
return в блоке finally «return» в блоке finally
блок «throw» внутри «finally» блок «throw» внутри блока «finally»
2.2.9General
Annotator Annotator
Использование шаблона файла по умолчанию
2.2.10 Импорт
2.2.11 Проблемы с J2ME Проблемы с J2ME
оператор if может быть заменен на && или ||
2.2.12Java 5 Java 5
цикл ‘for’, заменяемый на цикл ‘foreach’; ‘for’ можно заменить на цикл ‘foreach’
Выражение ‘indexOf ()’ заменяется выражением ‘contains ()’ ‘indexOf ()’ может быть заменено на ‘contains ()’
«StringBuffer» может быть «StringBuilder» «StringBuffer» может быть «StringBuilder»
Ненужный бокс
Ненужная распаковка
‘цикл while можно заменить на’ foreach ‘, а цикл’ может заменить ‘foreach’
2.2.13Java 7 Java 7
Явный тип можно заменить на <> Явный тип можно заменить на <>
«Попробуйте последний», замените «пробную» на ресурсы
2.2.14 Средства миграции на уровне языка Java
‘if’ replaceable with ‘switch’
2.2.15 Проблемы с Javadoc Проблемы с Javadoc
Оборванный Javadoc комментарий Оборванный Javadoc комментарий
В декларации есть проблемы с Javadoc
У декларации есть проблемы в Javadoc
2.2.16 Соглашения об именах
2.2.17 Числовые проблемы
Числовое переполнение
Восьмеричное целое число
Бессмысленное арифметическое выражение
2.2.18 Проблемы с производительностью
Redundant ‘String.toString ()’ Redundant ‘String.toString ()’
Redundant ‘substring (0)’ call Redundant ‘substring (0)’ call
Избыточный вызов String.format () Избыточный вызов String.format ()
Конкатенация строк в качестве аргумента для StringBuffer.append () вызывает конкатенацию строк в качестве аргумента для параметра вызова «StringBuffer.append ()»
Конкатенация строк в цикле Конкатенация строк в цикле
«StringBuffer» можно заменить на «String» «StringBuffer» можно заменить на «String»
2.2.19 Возможные ошибки
Коллекция добавлена в себя Коллекция добавлена в себя
Постоянные условия и исключения
Несоответствующий запрос и обновление коллекции Несоответствующий запрос и обновление коллекции
Несоответствующий запрос и обновление StringBuilder Несоответствующий запрос и обновление StringBuilder
@ NotNull / @ Обнуляемые проблемы @NotNull / @
Результат вызова метода игнорируется. Результат вызова метода игнорируется.
Оператор с пустым телом
Сравнение строк с использованием ‘==’ вместо ‘equals ()’ Используйте ‘==’ для сравнения строк, а не ‘equals ()’
Вызовы методов подозрительных коллекций Вызовы методов подозрительных коллекций
Сочетание подозрительной переменной / имени параметра Сочетание подозрительной переменной / имени параметра
Неиспользуемое назначение
2.2.20 Файлы свойств
2.2.21 Правописание
2.2.22Style стиль
Ненужная точка с запятой Ненужная точка с запятой
2.2.23 Подробные или избыточные кодовые конструкции
Создание избыточного массива
приведение типа с избыточностью
2.2.24XML XML
Устаревшее использование API в XML Устаревшее использование API в XML
Несвязанный префикс пространства имен XML Несвязанный префикс пространства имен XML
Объявление неиспользуемой схемы XML Объявление неиспользуемой схемы XML
XML-подсветка XML-подсветка
XML-тег пустое тело XML-тег пустое тело
Три, обычай линт
3.1 Создать проект
Для создания пользовательского Lint необходимо создать проект Java. В проекте должен быть представлен пакет Android Lint. Файл build.gradle проекта выглядит следующим образом:
Среди них lint-api — официальный интерфейс Android Lint. На основе этих интерфейсов вы можете получить информацию для анализа исходного кода, а lint-проверок — официальное правило проверки. Lint-Registry означает регистрировать пользовательские правила и упаковывать их в виде файлов jar.
3.2 Detector
Детектор является ядром пользовательских правил, его роль состоит в том, чтобы сканировать код для получения различной информации в коде, а затем на основе этой информации для напоминаний и отчетов, в этом сценарии нам нужно сканировать код Java, чтобы найти вызов метода getDrawable, Затем проанализируйте, является ли переданный объект Drawable векторным объектом Drawable. Если это так, необходимо сообщить об этом. Полный код выглядит следующим образом:
QMUIJavaVectorDrawableDetector наследуется от Detector и реализует интерфейс Detector.JavaScanner. Какой реализуемый интерфейс зависит от того, какой пользовательский Lint необходимо сканировать и какую информацию вы хотите получить из отсканированного содержимого. Android Lint предоставляет большое количество детекторов разных областей применения:
- Detector.BinaryResourceScanner предназначается для двоичных ресурсов, таких как различные растровые изображения в res / raw и других каталогах.
- Detector.ClassScanner больше ориентирован на сканирование классов, чем Detector.JavaScanner, и может получать различную информацию о классе
- Detector.GradleScanner сканирует против Gradle
- Detector.JavaScanner сканирует код Java
- Detector.ResourceFolderScanner сканирует каталог ресурсов, только сам каталог
- Detector.XmlScanner сканирует XML-файлы
- Detector.OtherFileScanner используется для других файлов, кроме указанных выше 6 случаев.
Различные интерфейсы определяют различные методы. Реализация пользовательского Lint фактически реализует различные методы в Detector. В приведенном выше примере возвращаемое значение getApplicableMethodNames указывает метод, который необходимо проверить, и visitMethod может получить проверенный метод. Соответствующая информация, этот метод содержит три параметра, функции которых:
- context Контекст здесь — это JavaContext, основная функция которого состоит в получении информации об основном проекте и отчете (включая местоположение кода, который необходимо сообщить, и т. д.).
- посетитель-посетитель — это ASTVisitor, то есть класс посетителя AST (абстрактного синтаксического дерева), Android Lint абстрагирует отсканированный код в AST, который удобен для разработчиков для получения информации в форме атрибутов узла, и посетитель может легко получить текущий узел Связанные узлы.
- node Это экземпляр MethodInvocation. MethodInvocation является подклассом AST в Android Lint. В приведенном выше примере узел представляет сканируемый метод, поэтому мы можем получить параметры сканируемого метода в виде атрибута узла. Различная информация.
В этом примере мы получаем параметры метода, получаем параметры Drawable путем обхода параметров, декомпозируем имя файла Drawable, а затем получаем путь ресурса основного проекта через контекст и взаимодействуем с вышивкой имени файла Drawable Фактический путь к файлу. После определения того, что файл существует, проверьте, содержит ли содержимое файла строку «вектор». Если это так, это означает, что разработчик передал вектор Drawable в обычном методе getDrawable, и, наконец, вызовите метод отчета контекста для отчета.
Стоит отметить, что в этом примере мы не создавали непосредственно экземпляр Drawable, а затем судили, является ли он векторным для рисования методом Drawable, а проверяли содержимое файла с помощью более громоздких шагов. Это связано с тем, что проект Android Lint является чистым проектом Java. Вы не можете использовать такие пакеты, как android.graphics, поэтому разработка будет более громоздкой.
3.3 Issue
Когда нужно сообщить о проблеме, ISSUE_JAVA_VECTOR_DRAWABLE передается в метод context.report. «Проблема» здесь в том, чтобы объявить правило, поэтому если вы определяете правило Lint, вам нужно определить проблему. Проблема создается методом класса Issue.create со следующими параметрами:
- id: уникальное значение проблемы, которое можно использовать для семантического описания проблемы. Этот идентификатор необходим при использовании аннотаций Java и атрибутов XML для маскировки Lint.
- резюме: Опишите проблему на высоком уровне, не давая решения.
- объяснение: опишите проблему подробно и дайте решение.
- категория: категорию проблемы, выберите из категорий, заданных системой, которые будут подробно описаны позже.
- приоритет: число от 1 до 10, обозначающее приоритет, а 10 — самый серьезный.
- серьезность: уровень серьезности. Выберите один из следующих вариантов: Фатальный, Ошибка, Предупреждение, Информационный и Игнорировать
Реализация. Отношение сопоставления между Detector и Issue необходимо передать в текущий класс Detector и область действия кода сканирования, например область Java-файлов, файлы ресурсов или каталоги.
Как показано на рисунке ниже, при возникновении проблемы в информации напоминания о проблеме будет отображаться соответствующий идентификатор проблемы и другая информация.

3.4 Category
Категория используется для классификации проблем. Система предоставила несколько часто используемых категорий. Системная проблема (то есть собственные правила проверки Android Lint) также использует эту категорию:
- Lint
- Корректность (Подкатегории Сообщений)
- Security
- Performance
- Юзабилити (Подкатегория Типография, Иконки)
- A11Y (Accessibility)
- I18N (Интернационализация, подкласс Rtl)
Если системная классификация не соответствует потребностям, вы также можете создать собственную классификацию:
Используйте следующим образом:
3.5 Registry
Последний шаг в создании пользовательского Lint — «Lint-Registry». Как упоминалось ранее, вам нужно объявить класс Regisry в build.gradle и упаковать его в jar:
Класс реестра — это зарегистрированная и созданная проблема, в качестве примера используется QMUIIssueRegistry:
QMUIIssueRegistry наследуется от IssueRegistry. Проблемы, зарегистрированные в Android Lint, регистрируются в IssueRegistry, а пользовательские проблемы могут передаваться через серию методов getIssues.
На этом этапе Java-проект для настройки Lint завершен.
3.6 Доступ к проекту
Официальное решение Google состоит в том, чтобы поместить файл jar в
/ .android / lint /. Если локально нет каталога lint, вы можете создать его самостоятельно. Этот метод относительно прост, но он также заставляет Android Lint работать во всех локальных проектах, что не очень гибко.
Создайте новый модуль в главном проекте, упакуйте его как aar и поместите файл jar в aar, чтобы каждый проект мог представить свой собственный Lint в виде aar, который является более гибким. Там не будет никакого вмешательства.
Содержимое модуля build.gradle выглядит следующим образом (в качестве примера рассмотрим QMUI Lint):
Среди них qmuilintrule — это модуль с пользовательскими правилами Lint, так что модуль, который должен быть упакован с aar, может получить файл jar и поместить его в путь сборки / промежуточные / lint /. После публикации aar в Bintray вам нужно ввести aar, где вам нужно использовать пользовательский Lint, например:
Кроме того, следует отметить, что при написании кода Lint с пользовательскими правилами, перестройке gradle после записи новый код не обязательно вступает в силу, необходимо перезапустить Android Studio, чтобы убедиться, что новый код вступил в силу.
How to solve this issue of Hardcoded string?
Hardcoding text attributes directly in layout files is bad for several reasons: * When creating configuration variations (for example for landscape or portrait)you have to repeat the actual text (and keep it up to date when making changes) * The application cannot be translated to other languages by just adding new translations for existing string resources. In Android Studio and Eclipse there are quickfixes to automatically extract this hardcoded string into a resource lookup.