Вам никогда не казалось, что вашей работе над кодом не помешали бы улучшения? IDE предлагают целый ряд инструментов, которые облегчают разработку программного обеспечения: от компиляции до отладки и не только. Однако можно легко упустить некоторые важные функции. В этой статье я познакомлю вас с четырьмя ценными инструментами Android Studio/IntelliJ IDEA, которые, возможно, не так широко известны среди разработчиков. Давайте вместе изучим эти инструменты и посмотрим, как они могут улучшить ваш опыт разработки.
1. Живые шаблоны (Live Templates)
Вы, наверное, заметили, что когда вы вводите main
в Kotlin-файл верхнего уровня и нажимаете Tab, Android Studio вставляет fun main() {}
в ваш файл. Аналогично, ввод comp
приводит к вставке @Composable fun FUNCTION_NAME() {}
, давая вам возможность указать имя для вашей composable функции. Live Templates позволяет нам делать это, позволяя легко вставлять общие фрагменты кода, просто используя аббревиатуру. Вообще, Live Templates поддерживает три типа шаблонов:
- Простые шаблоны: Они содержат только фиксированные обычные тексты. Например,
sout
вставляетprintln()
в Kotlin-файл. - Параметризованные шаблоны: Они содержат переменные, которые заменяются либо введенными пользователем, либо автоматически вычисленными IDE значениями. Например, использование
logd
внутри функцииonCreate
вставляетLog.d(TAG, "onCreate: ")
и позволяет ввести желаемое сообщение для лога. Здесь имя вложенной функции автоматически подставляется IDE. - Окружающие шаблоны: Они оборачивают блок выделенного кода указанным вами текстом. Например, вы можете создать живой шаблон, чтобы обернуть выбранный код внутри блока
try/catch
. Вы можете просмотреть список доступных шаблонов окружения, выделив блок кода и нажав CMD+Option+J на macOS или Ctrl+Alt+J на Windows.
Теперь давайте настроим один из доступных живых шаблонов и посмотрим, как он работает. Как объяснялось в пункте про параметризованные шаблоны, ввод logd внутри функции приводит к вставке Log.d(TAG, «FUNCTION_NAME: «). Лично я использую кастомный тег при отладке и хочу настроить его в соответствии со своими предпочтениями. Для этого:
- Перейдите в раздел Setting | Editor | Live Template. Здесь вы найдете полный список доступных живых шаблонов, сгруппированных по категориям. Вы можете просматривать, редактировать, удалять существующие или добавлять новые. В зависимости от используемого языка (Java или Kotlin) разверните категорию AndroidLog или AndroidLogKotlin и нажмите на элемент
logd
.
- Здесь вы можете просмотреть или отредактировать все настройки живого шаблона, такие как ключ аббревиатуры, текст описания, применимый контекст (например, Kotlin, Java и т. д.) и текст шаблона. Здесь используются два параметра. Нажмите на кнопку Edit Variables, чтобы посмотреть, как заменяются эти параметры.
- Вы можете видеть, что параметр
METHOD_NAME
заменяется результатом функцииkotlinFunctionName()
, которая возвращает имя вложенной функции, а параметрcontent
заменяется пользовательским вводом, что позволяет нам вставить желаемое сообщение для лога. Не стесняйтесь вводить дополнительные параметры, если это необходимо. - Теперь, когда вы хорошо знакомы с живым шаблоном, давайте настроим его в соответствии с нашими предпочтениями. Просто замените текст
TAG
в разделе Template Text наMY_CUSTOM_TAG
и установитеLog.d("MY_CUSTOM_TAG", String)
в качестве описания для шаблона. Результат должен выглядеть следующим образом:
- Кликните на кнопке OK, чтобы сохранить изменения. С этого момента при вводе logd в функции Kotlin будет вставляться наш настроенный шаблон.
Этот пример демонстрирует лишь один из множества вариантов использования этого инструмента. Я рекомендую изучить стандартные живые шаблоны для вдохновения и подумать о создании новых или изменении существующих шаблонов в соответствии с вашими потребностями. Для более подробного изучения, охватывающего предопределенные переменные, редактирование переменных, создание шаблонов окружения и многое другое, обратитесь к официальному сайту.
2. Анализ потока данных (Analyze Data Flow)
Представьте, что вы находитесь в функции верхнего уровня и организуете ее выполнение, вызывая другие функции и передавая им данные в качестве аргументов. Вам интересно, как эти переданные данные распространяются по этим функциям — используют ли они параметр сами или делегируют его другим. И наоборот, представьте себя во вложенной функции, которая получает параметры, и вам не терпится разгадать происхождение переданных значений. Именно здесь на помощь приходит инструмент Analyze Data Flow, который делает этот процесс исследования легким. С его помощью вы сможете без труда отследить потребителей и поставщиков конкретных данных.
Давайте рассмотрим простой пример, чтобы проиллюстрировать функциональность этого инструмента:
fun main() { b(5) } fun b(foo: Int) { println("$foo is passed to c as bar") c(bar = foo) } fun c(bar: Int) { println("bar is $bar") }
Предположим, вы находитесь в функции main
и хотите понять, как переданное значение 5
используется далее. Вместо того чтобы переходить к каждой вызываемой функции обычным способом, давайте воспользуемся инструментом Analyze Data Flow:
- Поместите курсор перед выражением
5
и в главном меню выберите Code | Analyze Code | Data Flow from Here. В качестве альтернативы можно использовать окно Find Action (как это делаю я) или вашу привязанную комбинацию клавиш для более быстрого доступа.
- В диалоговом окне предлагается указать область анализа. Выберите один из вариантов: весь проект, текущий модуль, текущий файл или пользовательский диапазон. Укажите свои предпочтения или оставьте все как есть, а затем нажмите кнопку Analyze.
- Появится окно Analyze Dataflow From, в котором будет отображен результат анализа. Здесь вы можете увидеть все случаи использования переданного параметра, понять, как с ним обращаются, и щелкнуть на них, чтобы перейти к соответствующим строкам кода.
И наоборот, если вы окажетесь внутри функции c
и захотите разгадать источники значений параметра bar
, а также конкретные переданные значения, воспользуйтесь аналогичным подходом. Вместо того чтобы выбрать Data Flow from Here, выберите Data Flow to Here.
Определите область действия, а затем нажмите на кнопку Analyze. Вы увидите, что в конечном итоге параметр bar берет начало в главной функции.
Эта функция невероятно мощная, она раскрывает древовидную структуру рабочего процесса. Она позволяет вносить улучшения по мере необходимости. В таких сценариях, как Jetpack Compose, с множеством вложенных композитных функций, этот инструмент может стать спасительным. Вы можете выполнить анализ состояния ViewModels, чтобы увидеть, как представление использует их и как ViewModel устанавливает для них значения. Более подробную информацию об этом инструменте можно найти на официальном сайте.
3. Инструменты рефакторинга
Рефакторинг — важнейшая практика в разработке программного обеспечения, предполагающая реструктуризацию существующего кода для улучшения его читабельности, понятности и удобства сопровождения. В прошлом разработчики выполняли эту задачу вручную, следя за тем, чтобы изменения не приводили к ошибкам. Однако современные интегрированные среды разработки (IDE), такие как Android Studio, предоставляют целый ряд автоматизированных инструментов рефакторинга, упрощая рабочий процесс разработчика и делая его безопасным и эффективным.
Давайте рассмотрим эту концепцию на практическом примере. Рассмотрим следующий код, генерирующий список студентов со случайными оценками и выводящий троих лучших на основе их оценок:
fun main() { printTop3Students() } data class Student(val name: String, val score: Int) fun printTop3Students() { (1..50) .map { Student("ST_$it", (Random.nextDouble() * 100).toInt()) } .sortedByDescending { it.score } .take(3) .forEachIndexed { index, student -> val rank = index + 1 println("${student.name} achieved the $rank rank with a score of ${student.score}.") } }
Давайте применим ряд рефакторингов шаг за шагом:
Вводим параметр
В исходном коде список студентов создается внутри функции printTop3Students
, что может помешать ее повторному использованию. Чтобы решить эту проблему, мы будем принимать список студентов в качестве параметра. Сначала выделите выражение создания списка и нажмите Ctrl + T в macOs и Ctrl + Alt + Shift + T в Windows, чтобы открыть список доступных рефакторингов для выбранного элемента.
Выберите Introduce Parameter из списка или воспользуйтесь альтернативными методами, например, используйте карту клавиш или щелкните правой кнопкой мыши на элементе и выберите его в разделе Refactor. Присвойте параметру осмысленное имя и наблюдайте за тем, как Android Studio плавно включает параметр students
в функцию printTop3Students
, автоматически передавая список студентов в место вызова.
Вводим переменную
Я хочу сделать код более читабельным, сохранив отсортированных студентов в переменной. Чтобы добиться этого, просто выделите выражение и выберите Introduce Variable из списка рефакторинга. Определите имя, которое будет иметь смысл. То же самое я сделаю с функцией take
. После этих двух исправлений наша функция printTop3Students
выглядит следующим образом:
Извлечение функции/метода
Вывод имени студента вместе с его рангом кажется мне отдельной функцией, и я хотел бы создать такую функцию. Для этого выберите выражение print и в списке рефакторинга выберите Extract Function/Method, указав для него имя. Теперь наш финальный код выглядит так:
Мы можем продолжить доработку кода, но я думаю, что текущее состояние достаточно хорошо объясняет идею. Эти инструменты рефакторинга могут сэкономить значительное количество времени в ваших ежедневных задачах по кодированию, и я настоятельно рекомендую освоить их для повышения эффективности. Полный список доступных рефакторингов и дополнительные советы можно найти на официальном сайте.
4. Постфикс дополнение (Postfix Completion)
Функция Postfix Completion упрощает процесс обертывания кода шаблона вокруг недавно набранного выражения. Например, ввод .val
после выражения и нажатие Tab или Enter превращает его в val [name] = expression
, позволяя указать имя новой переменной. Аналогично, ввод .if
изменяется на if (expression) {}
, а ввод .fori
после целочисленного выражения преобразуется в for (i in 0..expression)
. В этом контексте val
, if
и fori
служат постфиксными ключами.
Чтобы ознакомиться с полным списком предопределенных шаблонов и их описанием, перейдите в Settings | Editor | General | Postfix Completion. На момент написания этой статьи вы можете редактировать постфиксы доступных шаблонов, только щелкнув на них правой кнопкой мыши. К сожалению, изменение или удаление их функциональности не поддерживается.
Если вы хотите создать пользовательские шаблоны для поддерживаемых языков, обратитесь к этой статье, в которой рассказывается о создании пользовательских шаблонов для GO. Процесс аналогичен и для других языков.
Заключение
IDE оснащены множеством удобных функций, готовых улучшить ваши навыки программирования в любом сценарии. В этой статье мы рассмотрели некоторые инструменты, раскрыли их потенциал и привели практические примеры для повышения удобства использования.
Счастливого кодинга! 🚀