[Разработка под Android] Автоматический Code Improvement при коммите в Android Studio
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Работать с гитом в Android Studio, как известно, можно двумя способами.
Первый способ классический — использовать консоль. Плюсом такого подхода являются в первую очередь надежность. GUI может залагать и например, зависнуть на этапе rebase так, что abort/continue/переключение на другую ветку не поможет. Консольные команды вам в помощь, они всегда безотказны.
Второй способ — использовать GUI, предоставляемый Android Studio. Плюсы очевидны — меньший порог входа, более понятно, что вообще можно делать. А также есть различные плюшки от самой студии для удобства работы с гитом. Об одном из них и пойдет речь. Кстати, используя GUI, тоже можно оставлять в покое мышку и использовать hotkey
Используемые Hotkey в статье
Shift+Shift (двойное нажатие shift) — Окно поиска. Позволяет искать как код/ресурсы, так и различные действия и настройки.
Ctrl+Alt+L (⌘+⌥+L) → Форматирование кода
Shift+Ctrl+Alt+L (⇧+⌘+⌥+L) → Форматирование кода → Форматирование кода с параметрами.
вызывает данное окно
SPL
О чем вообще речь и где найти?
Неактуальные импорты, пустые строки, пробелы вместо табов — эти вещи бесят, если они попадают в готовый код, предназначенный для pull request. Исправить это легко, используя hotkey Ctrl+Alt+L, однако часто мы забываем это делать.
Idea/AndroidStudio позволяет проводить эти действия автоматически, в последний момент перед коммитом
При использовании commit'а через Android Studio можно увидеть такого вида окно:
Нас интересуют галочки, которые находятся справа от списка файлов, в блоке Before Commit. При активации этих помощников, они будут автоматически применяться при каждом коммите
Чем именно мне помогут эти галочки?
✓ Reformat code
Данное улучшение приводит код в соответствии с вашим code style. Действие полностью аналогично ctrl+shift+alt+L с включенным clean up.
Настроить code style можно здесь Settings → Editor → Code Style
Tab and Indents
SPL
Применяет отступы строк в соответствии с code style (Подробно в Code Style, в одноименном разделе)
В примере пробелы, используемые для формирования отступа (отмечены точками), будут замены табами (отмечены стрелкой)
До коммита
class CleanTab(context: Context) {
....val date = Date()
....val button = Button(context)
....val textView = TextView(context)
....val ratingBar = RatingBar(context)
....val imageView = ImageView(context)
}
После коммита
class CleanTab(context: Context) {
-> val date = Date()
-> val button = Button(context)
-> val textView = TextView(context)
-> val ratingBar = RatingBar(context)
-> val imageView = ImageView(context)
}
Spaces
SPL
Форматирует все пробелы в коде в соответствии с code-style.
Будут удалены лишние пробелы в конструкторе Date, добавлены пробелы между объявлением переменной button и =, а также между списком аргументов args в main и {
До коммита
class CleanSpaces(context:Context) {
val date = Date( )
val button= Button(context)
fun main(arg: Args){
}
}
После коммита
class CleanSpaces(context: Context) {
val date = Date()
val button = Button(context)
fun main(arg: Args) {
}
}
Wrapping and Braces
SPL
Этот блок управляет переносом строк. Переносятся как сами строки кода, так и закрывающие/открывающие скобки.
Строчка else, а также строчка catch должны располагаться на той же линии, что и закрывающая скобка (так настроено в code style)
Общее количество символов на строке с функцией manyArguments вышло за 80 знаков(настроено в code style), поэтому аргументы будут перенесены на новую строку
До коммита
class CleanWrappingAndBraces {
fun condition() {
if (liveData != null) {
<..>
}
else {
<..>
}
}
fun catching() {
try {
<..>
}
catch (e: Exception) {
<..>
}
}
fun manyArguments(userId: Int, issuerCountryId: String, sendingCountryId: String, receivingCountryId: String) {
}
}
После коммита
class CleanWrappingAndBraces {
fun condition() {
if (liveData != null) {
<..>
} else {
<..>
}
}
fun catching() {
try {
<..>
} catch (e: Exception) {
<..>
}
}
fun manyArguments(userId: Int, issuerCountryId: String,
sendingCountryId: String,
receivingCountryId: String) {
}
Blank Lines
SPL
Регулирует максимальное и минимальное количество пустых строчек в коде. (Подробно в Code Style, в одноименном разделе)
В данном примере удалит лишние строки от последней функции до }, а также 2 лишних пустых строчки между функциями
До коммита
class CleanBlank {
fun foo() {
}
fun bar() {
}
}
После коммита
class CleanBlank {
fun foo() {
}
fun bar() {
}
}
Rearrange code
Располагает атрибуты и элементы в том порядке, который соответствует код-стайлу. Работает в XML и HTML файлах. Настроить расположение можно в Setting → Editor → CodeStyle → XML/HTML → Arrangement
Внимание! неправильная настройка может привести к печальным последствиям. Rearrange может влиять на очередность элементов, что может привести к неправильной работе в файлах, чувствительных к расположению. Пример: в LinearLayout, при сортировке по алфавитному порядку, элемент Button может переместится выше TextView, хотя по дизайну такого быть не должно. Выход — настраивать расположение ТОЛЬКО атрибутов
Сортировка
SPL
В данном примере xmlns расположились в трех первых строчках и строго по порядку, определенному в code-style(xmlns:android на первой строчке, остальные xmlns:<...> в алфавитном порядке.
Обратите внимание, xmlns:tools и xmlns:app не были удалены даже несмотря на то, что нет случаев их использования. Это говорит о том, что rearrange влияет только на расположение элементов
До коммита
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
xmlns:tools="http://schemas.android.com/tools" android:layout_height="match_parent"
android:orientation="vertical" xmlns:app="http://schemas.android.com/apk/res-auto">
</LinearLayout>
После коммита
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
Сортировка
SPL
В данном примере блок с атрибутами android:padding изменит порядок в соответствии с code-style. Также атрибут style расположится сразу за android:id
До коммита
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
tools:srcCompat="@tools:sample/avatars" />
<TextView
style="@style/TextAppearance.MaterialComponents.Body1"
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello World" />
</LinearLayout>
После коммита
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingTop="8dp"
android:paddingRight="8dp"
android:paddingBottom="8dp"
tools:srcCompat="@tools:sample/avatars" />
<TextView
android:id="@+id/title"
style="@style/TextAppearance.MaterialComponents.Body1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello World" />
</LinearLayout>
Optimize import
Следит за чистотой блока импортов и приводит в правильный вид, а также проверяет на соответствие code style. Само действие полностью аналогично ctrl+shift+alt+L с включенным optimize import.
Удаление неиспользуемых импортов
SPL
В данном примере при optimize imports import java.util.* будет удален, так как нет полей или методов, нуждающихся в нем
До коммита
import android.content.Context
import android.widget.Button
import java.util.*
class RemoveUnused(context: Context) {
val button = Button(context)
}
После коммита
import android.content.Context
import android.widget.Button
class RemoveUnused(context: Context) {
val button = Button(context)
}
Объединение импортов
SPL
Если n или более классов импортируются из одного пакета, то такой импорт будет заменен импортом всего пакета.
Если m или более enum или java static импортируется из одного класса, то такой импорт будет заменен на импорт всего класса
Оба параметра задаются в Settings → Editor → Code Style → Kotlin → Imports
В данном примере множественные импорты из пакета android.widget будут заменены на android.widget.*
До коммита
import android.content.Context
import android.widget.Button
import android.widget.ImageButton
import android.widget.ImageView
import android.widget.TextView
import android.widget.RatingBar
import java.util.*
class MergeImport(context: Context) {
<..>
}
После коммита
import android.content.Context
import android.widget.*
import java.util.*
class MergeImport(context: Context) {
<..>
}
В том случае, если стоит настройка не объединять импорты(m = 0, n=0), объединенные импорты(импорт пакета) будут заменены импортом каждого класса/функции/поля отдельно.
В случае ниже import android.widget. и import java.util. будут упразднены
До коммита
import android.content.Context
import android.widget.*
import java.util.*
class MergeImport(context: Context) {
<..>
После коммита
import android.content.Context
import android.widget.Button
import android.widget.ImageButton
import android.widget.ImageView
import android.widget.TextView
import android.widget.RatingBar
import java.util.*
class MergeImport(context: Context) {
<..>
}
Расположение по алфавиту
SPL
После применения, все импорты отсортируются, и будут удобно располагаться в алфавитном порядке
До коммита
import android.content.Context
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import java.util.*
import android.widget.RatingBar
class SortImport(context: Context) {
<..>
}
После коммита
import android.content.Context
import android.widget.Button
import android.widget.ImageView
import android.widget.RatingBar
import android.widget.TextView
import java.util.*
class SortImport(context: Context) {
<..>
}
Perform code analysis
Помогает находить проблемные места. Носит информационный характер и никак не меняет код. Самые частые случаи — неиспользуемые параметры, переменные, использование кода, помеченного как Deprecated
Пример кода с множествеными нарушениями
SPL
Check TODO
Очень полезная галочка, помогает не забыть о новых TODO, которые были поставлены именно в этом коммите. Более того, студия позволяет отслеживать не только //TODO, но и //FIXME, а также любые собственные todo, которые были добавлены через Setting → Editor → TODO.
Также можно фильтровать список todo, которые студия будет проверять.
Так выглядит подсказка студии, что был добавлен todo. При нажатии на review он покажет список всех новых todo и предложит их пересмотреть
SPL
Clean up
Очень помогает держать код в чистоте. Удаляет избыточный код (см. примеры), заменяет deprecated функции. Действие полностью аналогично Actions → Code cleanup. Достаточно интересная функция, но вместе с этим может быть и опасной.
Из замеченных особенностей можно выделить две основные:
- замена deprecated методов (подробнее ниже)
- непонятную замену вызова методов view в презентере в одном из личных случаев
! Обязательно пересматривайте получившийся коммит, если используете данную функцию!
Redutant code
SPL
После применения удалятся элвис-операторы, т.к. были применены к non-nullable переменным
До коммита
data class User(val firstName: String, val secondName: String)
val user = User("Василий", "Пупкин")
fun getUserFullName(): String {
val firstName = user?.firstName
val secondName = user.secondName ?: return firstName
return "$firstName $secondName"
}
После коммита
data class User(val firstName: String, val secondName: String)
val user = User("Василий", "Пупкин")
fun getUserFullName(): String {
val firstName = user.firstName
val secondName = user.secondName
return "$firstName $secondName"
}
После применения удалится оператор public, т.к. конкретно в этом случае лишний
До коммита
data class User(val firstName: String, val secondName: String)
val user = User("Василий", "Пупкин")
public fun getUserFullName(): String {
val firstName = user.firstName
val secondName = user.secondName
return "$firstName $secondName"
}
После коммита
data class User(val firstName: String, val secondName: String)
val user = User("Василий", "Пупкин")
fun getUserFullName(): String {
val firstName = user.firstName
val secondName = user.secondName
return "$firstName $secondName"
}
После применения удалится вызов конструктора
До коммита
class ExecutionClass(val exec: () -> Unit)
val exec = ExecutionClass() {
doIt()
}
После коммита
class ExecutionClass(val exec: () -> Unit)
val exec = ExecutionClass {
doIt()
}
Deprecated код
SPL
Если в аннотации deprecated указан ReplaceWith(), то при cleanup старые методы и классы будут заменены в соответствии с этой пометкой. Надо быть очень внимательным с применением этой возможности, так как работает все очень банально — название старого метода меняется ровно на то, что было указано в ReplaceWith(). Анализатор не проверят даже существует ли такой код. Поэтому неправильно указание нового класса/метода может привести к невозможности компиляции кода. И даже если такая функция/класс существует, даже если у нее одинаковая сигнатура(что анализатор также НЕ проверяет), то это может привести к другой проблеме, необходимо было не просто заменить одну функцию на другую, но и изменить сценарий использования. Код в таком случае скомпилируется, но не будет правильно работать
Заменит старый метод и класс на новые
До коммита
@Deprecated("Будет удален", ReplaceWith("newMethod()"))
fun oldMethod() = Unit
fun newMethod() = Unit
@Deprecated("Будет удален", ReplaceWith("NewClass"))
class OldClass
class NewClass
class GetDeprecatedCodeUseCase(val clazz: OldClass) {
init {
val initData = oldMethod()
}
}
После коммита
@Deprecated("Будет удален", ReplaceWith("newMethod()"))
fun oldMethod() = Unit
fun newMethod() = Unit
@Deprecated("Будет удален", ReplaceWith("NewClass"))
class OldClass
class NewClass
class GetDeprecatedCodeUseCase(val clazz: NewClass) {
init {
val initData = newMethod()
}
}
Выводы и рекомендация
Помощники, предоставленные Android Studio могут здорово облегчить жизнь вам и вашим коллегам. Да, все действия можно провести и вручную перед отправкой на коммит, но все же не имея привычки так делать, легко пропустить неправильной код дальше. Правильное использование может освободить вас от мыслей о том, что надо следить за каждой запятой и каждым пробелом.
Из приведенных выше примеров можно понять несколько моментов:
Optimize import и Reformat code можно использовать безбоязненно. Они влияют только на форматирование и явные огрехи.
Rearrange и Clean up необходимо использовать аккуратно. Да, они в целом могут хорошо помочь и выловить уже что-то посерьезнее, но при неправильной настройке (Rearrange) или неоднозначном коде (Clean up) помощники могут сильно ошибиться
Check TODO и Perform code analysis также можно использовать безбоязненно. Они никаким образом не влияют на код, только дают назойливые подсказки. Да, если у вас в проекте все полностью построено на TODO и Deprecated коде, то отбоя от них не будет, и они больше будут мозолить глаза. Но если у вас в проекте достаточно чистый код и такие моменты стараетесь минимизировать, то помощники будут давать отличный шанс пересмотреть код, где вы могли допустить упущение.
===========
Источник:
habr.com
===========
Похожие новости:
- [Разработка веб-сайтов, JavaScript, ReactJS] Почему мы выбрали MobX, а не Redux, и как его использовать эффективнее
- [Open source, JavaScript, Я пиарюсь] Javascript фреймворк разработки бизнес приложений
- [Разработка под Android] Compose. Jetpack Compose
- [Монетизация мобильных приложений, Платежные системы, Разработка мобильных приложений, Разработка под Android] Таргетирование уведомлений, управление ценами в разных регионах и другие возможности HMS для интернет-платежей
- [Разработка под iOS, Разработка под Android, Карьера в IT-индустрии, Конференции, Flutter] 22 октября приглашаем на онлайн-митап Hot Mobile: iOS, Android, Flutter
- [Java, Анализ и проектирование систем, Промышленное программирование, Распределённые системы] Интеграция в стиле BPM
- [JavaScript, Тестирование мобильных приложений, ReactJS] Моки не кусаются! Осваиваем мокинг с React Testing Library (перевод)
- Открыты исходные тексты GitHub Docs
- [Разработка под Android, Хакатоны, Kotlin, Искусственный интеллект] Челлендж по разговорному ИИ на хакатоне Junction: создай чатбота или голосовой навык и выиграй 10 000 евро
- [JavaScript, ReactJS, Программирование, Разработка веб-сайтов] Мифы о useEffect (перевод)
Теги для поиска: #_razrabotka_pod_android (Разработка под Android), #_android_studio, #_kotlin, #_java, #_razrabotka_pod_android (
Разработка под Android
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 20:11
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Работать с гитом в Android Studio, как известно, можно двумя способами. Первый способ классический — использовать консоль. Плюсом такого подхода являются в первую очередь надежность. GUI может залагать и например, зависнуть на этапе rebase так, что abort/continue/переключение на другую ветку не поможет. Консольные команды вам в помощь, они всегда безотказны. Второй способ — использовать GUI, предоставляемый Android Studio. Плюсы очевидны — меньший порог входа, более понятно, что вообще можно делать. А также есть различные плюшки от самой студии для удобства работы с гитом. Об одном из них и пойдет речь. Кстати, используя GUI, тоже можно оставлять в покое мышку и использовать hotkey Используемые Hotkey в статье Shift+Shift (двойное нажатие shift) — Окно поиска. Позволяет искать как код/ресурсы, так и различные действия и настройки. Ctrl+Alt+L (⌘+⌥+L) → Форматирование кода Shift+Ctrl+Alt+L (⇧+⌘+⌥+L) → Форматирование кода → Форматирование кода с параметрами. вызывает данное окноSPLО чем вообще речь и где найти? Неактуальные импорты, пустые строки, пробелы вместо табов — эти вещи бесят, если они попадают в готовый код, предназначенный для pull request. Исправить это легко, используя hotkey Ctrl+Alt+L, однако часто мы забываем это делать. Idea/AndroidStudio позволяет проводить эти действия автоматически, в последний момент перед коммитом При использовании commit'а через Android Studio можно увидеть такого вида окно: Нас интересуют галочки, которые находятся справа от списка файлов, в блоке Before Commit. При активации этих помощников, они будут автоматически применяться при каждом коммите Чем именно мне помогут эти галочки? ✓ Reformat code Данное улучшение приводит код в соответствии с вашим code style. Действие полностью аналогично ctrl+shift+alt+L с включенным clean up. Настроить code style можно здесь Settings → Editor → Code Style Tab and IndentsSPLПрименяет отступы строк в соответствии с code style (Подробно в Code Style, в одноименном разделе)
В примере пробелы, используемые для формирования отступа (отмечены точками), будут замены табами (отмечены стрелкой)
class CleanTab(context: Context) {
....val date = Date() ....val button = Button(context) ....val textView = TextView(context) ....val ratingBar = RatingBar(context) ....val imageView = ImageView(context) } После коммита class CleanTab(context: Context) {
-> val date = Date() -> val button = Button(context) -> val textView = TextView(context) -> val ratingBar = RatingBar(context) -> val imageView = ImageView(context) } SpacesSPLФорматирует все пробелы в коде в соответствии с code-style.
Будут удалены лишние пробелы в конструкторе Date, добавлены пробелы между объявлением переменной button и =, а также между списком аргументов args в main и {
class CleanSpaces(context:Context) {
val date = Date( ) val button= Button(context) fun main(arg: Args){ } } После коммита class CleanSpaces(context: Context) {
val date = Date() val button = Button(context) fun main(arg: Args) { } } Wrapping and BracesSPLЭтот блок управляет переносом строк. Переносятся как сами строки кода, так и закрывающие/открывающие скобки.
Строчка else, а также строчка catch должны располагаться на той же линии, что и закрывающая скобка (так настроено в code style)
Общее количество символов на строке с функцией manyArguments вышло за 80 знаков(настроено в code style), поэтому аргументы будут перенесены на новую строку class CleanWrappingAndBraces {
fun condition() { if (liveData != null) { <..> } else { <..> } } fun catching() { try { <..> } catch (e: Exception) { <..> } } fun manyArguments(userId: Int, issuerCountryId: String, sendingCountryId: String, receivingCountryId: String) { } } После коммита class CleanWrappingAndBraces {
fun condition() { if (liveData != null) { <..> } else { <..> } } fun catching() { try { <..> } catch (e: Exception) { <..> } } fun manyArguments(userId: Int, issuerCountryId: String, sendingCountryId: String, receivingCountryId: String) { } Blank LinesSPLРегулирует максимальное и минимальное количество пустых строчек в коде. (Подробно в Code Style, в одноименном разделе)
В данном примере удалит лишние строки от последней функции до }, а также 2 лишних пустых строчки между функциями
class CleanBlank {
fun foo() { } fun bar() { } } После коммита class CleanBlank {
fun foo() { } fun bar() { } } Rearrange code Располагает атрибуты и элементы в том порядке, который соответствует код-стайлу. Работает в XML и HTML файлах. Настроить расположение можно в Setting → Editor → CodeStyle → XML/HTML → Arrangement Внимание! неправильная настройка может привести к печальным последствиям. Rearrange может влиять на очередность элементов, что может привести к неправильной работе в файлах, чувствительных к расположению. Пример: в LinearLayout, при сортировке по алфавитному порядку, элемент Button может переместится выше TextView, хотя по дизайну такого быть не должно. Выход — настраивать расположение ТОЛЬКО атрибутов
СортировкаSPLВ данном примере xmlns расположились в трех первых строчках и строго по порядку, определенному в code-style(xmlns:android на первой строчке, остальные xmlns:<...> в алфавитном порядке.
Обратите внимание, xmlns:tools и xmlns:app не были удалены даже несмотря на то, что нет случаев их использования. Это говорит о том, что rearrange влияет только на расположение элементов <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" xmlns:tools="http://schemas.android.com/tools" android:layout_height="match_parent" android:orientation="vertical" xmlns:app="http://schemas.android.com/apk/res-auto"> </LinearLayout> После коммита <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> </LinearLayout> СортировкаSPLВ данном примере блок с атрибутами android:padding изменит порядок в соответствии с code-style. Также атрибут style расположится сразу за android:id
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ImageView android:id="@+id/imageView" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="8dp" android:paddingBottom="8dp" android:paddingLeft="8dp" android:paddingRight="8dp" tools:srcCompat="@tools:sample/avatars" /> <TextView style="@style/TextAppearance.MaterialComponents.Body1" android:id="@+id/title" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Hello World" /> </LinearLayout> После коммита <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ImageView android:id="@+id/imageView" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="8dp" android:paddingTop="8dp" android:paddingRight="8dp" android:paddingBottom="8dp" tools:srcCompat="@tools:sample/avatars" /> <TextView android:id="@+id/title" style="@style/TextAppearance.MaterialComponents.Body1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Hello World" /> </LinearLayout> Optimize import Следит за чистотой блока импортов и приводит в правильный вид, а также проверяет на соответствие code style. Само действие полностью аналогично ctrl+shift+alt+L с включенным optimize import. Удаление неиспользуемых импортовSPLВ данном примере при optimize imports import java.util.* будет удален, так как нет полей или методов, нуждающихся в нем
import android.content.Context
import android.widget.Button import java.util.* class RemoveUnused(context: Context) { val button = Button(context) } После коммита import android.content.Context
import android.widget.Button class RemoveUnused(context: Context) { val button = Button(context) } Объединение импортовSPLЕсли n или более классов импортируются из одного пакета, то такой импорт будет заменен импортом всего пакета.
Если m или более enum или java static импортируется из одного класса, то такой импорт будет заменен на импорт всего класса Оба параметра задаются в Settings → Editor → Code Style → Kotlin → Imports В данном примере множественные импорты из пакета android.widget будут заменены на android.widget.*
import android.content.Context
import android.widget.Button import android.widget.ImageButton import android.widget.ImageView import android.widget.TextView import android.widget.RatingBar import java.util.* class MergeImport(context: Context) { <..> } После коммита import android.content.Context
import android.widget.* import java.util.* class MergeImport(context: Context) { <..> } В том случае, если стоит настройка не объединять импорты(m = 0, n=0), объединенные импорты(импорт пакета) будут заменены импортом каждого класса/функции/поля отдельно.
В случае ниже import android.widget. и import java.util. будут упразднены import android.content.Context
import android.widget.* import java.util.* class MergeImport(context: Context) { <..> После коммита import android.content.Context
import android.widget.Button import android.widget.ImageButton import android.widget.ImageView import android.widget.TextView import android.widget.RatingBar import java.util.* class MergeImport(context: Context) { <..> } Расположение по алфавитуSPLПосле применения, все импорты отсортируются, и будут удобно располагаться в алфавитном порядке
import android.content.Context
import android.widget.Button import android.widget.ImageView import android.widget.TextView import java.util.* import android.widget.RatingBar class SortImport(context: Context) { <..> } После коммита import android.content.Context
import android.widget.Button import android.widget.ImageView import android.widget.RatingBar import android.widget.TextView import java.util.* class SortImport(context: Context) { <..> } Perform code analysis Помогает находить проблемные места. Носит информационный характер и никак не меняет код. Самые частые случаи — неиспользуемые параметры, переменные, использование кода, помеченного как Deprecated Пример кода с множествеными нарушениямиSPLCheck TODO Очень полезная галочка, помогает не забыть о новых TODO, которые были поставлены именно в этом коммите. Более того, студия позволяет отслеживать не только //TODO, но и //FIXME, а также любые собственные todo, которые были добавлены через Setting → Editor → TODO. Также можно фильтровать список todo, которые студия будет проверять. Так выглядит подсказка студии, что был добавлен todo. При нажатии на review он покажет список всех новых todo и предложит их пересмотретьSPLClean up Очень помогает держать код в чистоте. Удаляет избыточный код (см. примеры), заменяет deprecated функции. Действие полностью аналогично Actions → Code cleanup. Достаточно интересная функция, но вместе с этим может быть и опасной. Из замеченных особенностей можно выделить две основные:
! Обязательно пересматривайте получившийся коммит, если используете данную функцию!
Redutant codeSPLПосле применения удалятся элвис-операторы, т.к. были применены к non-nullable переменным
data class User(val firstName: String, val secondName: String)
val user = User("Василий", "Пупкин") fun getUserFullName(): String { val firstName = user?.firstName val secondName = user.secondName ?: return firstName return "$firstName $secondName" } После коммита data class User(val firstName: String, val secondName: String)
val user = User("Василий", "Пупкин") fun getUserFullName(): String { val firstName = user.firstName val secondName = user.secondName return "$firstName $secondName" } После применения удалится оператор public, т.к. конкретно в этом случае лишний
data class User(val firstName: String, val secondName: String)
val user = User("Василий", "Пупкин") public fun getUserFullName(): String { val firstName = user.firstName val secondName = user.secondName return "$firstName $secondName" } После коммита data class User(val firstName: String, val secondName: String)
val user = User("Василий", "Пупкин") fun getUserFullName(): String { val firstName = user.firstName val secondName = user.secondName return "$firstName $secondName" } После применения удалится вызов конструктора
class ExecutionClass(val exec: () -> Unit)
val exec = ExecutionClass() { doIt() } После коммита class ExecutionClass(val exec: () -> Unit)
val exec = ExecutionClass { doIt() } Deprecated кодSPLЕсли в аннотации deprecated указан ReplaceWith(), то при cleanup старые методы и классы будут заменены в соответствии с этой пометкой. Надо быть очень внимательным с применением этой возможности, так как работает все очень банально — название старого метода меняется ровно на то, что было указано в ReplaceWith(). Анализатор не проверят даже существует ли такой код. Поэтому неправильно указание нового класса/метода может привести к невозможности компиляции кода. И даже если такая функция/класс существует, даже если у нее одинаковая сигнатура(что анализатор также НЕ проверяет), то это может привести к другой проблеме, необходимо было не просто заменить одну функцию на другую, но и изменить сценарий использования. Код в таком случае скомпилируется, но не будет правильно работать
Заменит старый метод и класс на новые
@Deprecated("Будет удален", ReplaceWith("newMethod()"))
fun oldMethod() = Unit fun newMethod() = Unit @Deprecated("Будет удален", ReplaceWith("NewClass")) class OldClass class NewClass class GetDeprecatedCodeUseCase(val clazz: OldClass) { init { val initData = oldMethod() } } После коммита @Deprecated("Будет удален", ReplaceWith("newMethod()"))
fun oldMethod() = Unit fun newMethod() = Unit @Deprecated("Будет удален", ReplaceWith("NewClass")) class OldClass class NewClass class GetDeprecatedCodeUseCase(val clazz: NewClass) { init { val initData = newMethod() } } Выводы и рекомендация Помощники, предоставленные Android Studio могут здорово облегчить жизнь вам и вашим коллегам. Да, все действия можно провести и вручную перед отправкой на коммит, но все же не имея привычки так делать, легко пропустить неправильной код дальше. Правильное использование может освободить вас от мыслей о том, что надо следить за каждой запятой и каждым пробелом. Из приведенных выше примеров можно понять несколько моментов: Optimize import и Reformat code можно использовать безбоязненно. Они влияют только на форматирование и явные огрехи. Rearrange и Clean up необходимо использовать аккуратно. Да, они в целом могут хорошо помочь и выловить уже что-то посерьезнее, но при неправильной настройке (Rearrange) или неоднозначном коде (Clean up) помощники могут сильно ошибиться Check TODO и Perform code analysis также можно использовать безбоязненно. Они никаким образом не влияют на код, только дают назойливые подсказки. Да, если у вас в проекте все полностью построено на TODO и Deprecated коде, то отбоя от них не будет, и они больше будут мозолить глаза. Но если у вас в проекте достаточно чистый код и такие моменты стараетесь минимизировать, то помощники будут давать отличный шанс пересмотреть код, где вы могли допустить упущение. =========== Источник: habr.com =========== Похожие новости:
Разработка под Android ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 20:11
Часовой пояс: UTC + 5