2. Передавайте только ссылку (путь) на данные.
3. Используйте механизмы, такие как URI или ContentProvider, для безопасного доступа к большим данным. Это предотвратит ошибки превышения размера данных в Intent.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥2
Sealed классы являются мощным инструментом для создания ограниченных иерархий классов, что обеспечивает безопасное и предсказуемое использование классов.
Все классы, которые наследуются от sealed класса, должны быть определены в одном файле с самим sealed классом. Это ограничение введено для обеспечения полной контрольной иерархии и предотвращения добавления новых подтипов в другом месте.
sealed class Result {
class Success(val data: String) : Result()
class Error(val exception: Exception) : Result()
} Sealed класс не может быть интерфейсом. Если вам нужно определить ограниченную иерархию интерфейсов, вы должны использовать обычные интерфейсы и sealed классы вместе.
Хотя sealed классы и являются абстрактными по своей природе (их нельзя напрямую инстанцировать), они не могут быть явно помечены как
abstract. Sealed классы и их подтипы не могут быть
private. Они должны быть либо public, либо internal, чтобы их можно было использовать в рамках всего файла иерархии.Sealed класс не может наследоваться от другого класса, кроме
Any. Это связано с тем, что sealed классы уже имеют специфическое предназначение и их иерархия должна быть полностью определена в одном месте.Sealed классы могут быть использованы для классов и объектов, но не могут использоваться для определения интерфейсов.
sealed class Operation {
class Addition(val value: Int) : Operation()
class Subtraction(val value: Int) : Operation()
object NoOp : Operation()
}
fun execute(operation: Operation, base: Int): Int {
return when (operation) {
is Operation.Addition -> base + operation.value
is Operation.Subtraction -> base - operation.value
Operation.NoOp -> base
}
}Это позволяет использовать исчерпывающие выражения
when, которые не требуют блока else, если все подтипы покрыты.Это делает код более предсказуемым и безопасным.
Это делает код более читаемым и менее подверженным ошибкам.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥2
1. Это нужно, чтобы избегать рефлексии и писать более читаемый код.
2. Пример: фильтрация элементов коллекции по типу list.filterIsInstance<T>().
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8👍2
При создании классов по сравнению с Java произошли несколько значительных изменений и упрощений. Kotlin предлагает более лаконичный и выразительный синтаксис, что делает код более читаемым и удобным.
В Kotlin объявление классов и их конструкторов значительно упрощено.
В Java
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}В Kotlin
class Person(val name: String, val age: Int)
В Java для объявления статических членов используется ключевое слово
static. В Kotlin вместо этого используются companion object.В Java
public class MyClass {
public static final String CONSTANT = "constant";
public static void staticMethod() {
// Some code
}
}В Kotlin
class MyClass {
companion object {
const val CONSTANT = "constant"
@JvmStatic
fun staticMethod() {
// Some code
}
}
}Kotlin предоставляет специальный тип классов —
data классы, которые автоматически генерируют методы equals(), hashCode(), toString(), copy(), и componentN().В Java
public class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
// Implementation
}
@Override
public int hashCode() {
// Implementation
}
@Override
public String toString() {
// Implementation
}
}В Kotlin
data class User(val name: String, val age: Int)
В Kotlin свойства объявляются напрямую, и методы доступа (геттеры и сеттеры) генерируются автоматически.
В Java
public class Rectangle {
private int width;
private int height;
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
}В Kotlin
class Rectangle(var width: Int, var height: Int)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
2. Nothing: указывает, что функция никогда не завершится успешно (например, выбрасывает исключение).
3. Any: корневой тип для всех объектов в Kotlin.
4. Nullable типы: добавляют ?, чтобы разрешить null в значении.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥3
При наследовании
data class от какого-либо суперкласса в Kotlin, важно понимать, как работают свойства (поля) суперкласса и как они влияют на функциональность и структуру data class. Поля (свойства), объявленные в суперклассе, автоматически становятся доступными в классе-наследнике. Вы можете использовать их в наследуемом классе как обычно. Однако свойства суперкласса не участвуют в автоматически сгенерированных функциях
equals(), hashCode(), и toString() для data class.У
data class Kotlin генерирует функции equals(), hashCode(), toString(), copy() и другие. Эти функции работают только с параметрами, объявленными в первичном конструкторе data-класса. Поля, которые находятся в суперклассе, не участвуют в этих функциях.Это связано с тем, что контракт
data class предполагает, что все его ключевые данные (data) определяются только параметрами первичного конструктора. Это позволяет гарантировать, что две одинаковые сущности будут сравниваться и обрабатываться корректно, основываясь только на данных самого data class.// Суперкласс с полем name
open class Person(val name: String)
// Наследуемый data-класс
data class Employee(val id: Int, val position: String) : Person(name = "Default")
val employee1 = Employee(1, "Developer")
val employee2 = Employee(1, "Developer")
println(employee1 == employee2) // true, так как сравнение основано только на id и position
println(employee1.toString()) // Employee(id=1, position=Developer)
Если вы хотите, чтобы поля суперкласса учитывались в логике
equals() или hashCode(), вам нужно переопределить эти функции вручную.data class Employee(val id: Int, val position: String) : Person(name = "Default") {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is Employee || !super.equals(other)) return false
return id == other.id && position == other.position && name == other.name
}
override fun hashCode(): Int {
return 31 * super.hashCode() + id.hashCode() + position.hashCode()
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14
1. Они взаимодействуют через Intent, который передаёт команды и данные.
2. Каждый компонент регистрируется в AndroidManifest.xml.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8👍7
Различия между Android 7 (Nougat) и Android 8 (Oreo) заключаются в добавленных функциях, изменениях в производительности, безопасности, работе приложений и пользовательском интерфейсе.
Android 7 (Nougat):
Впервые представлена технология Doze on the Go, которая снижает энергопотребление приложений, когда устройство неактивно.
Улучшена многозадачность благодаря Split-Screen Mode (режим разделения экрана).
Android 8 (Oreo):
Введена система Vitals, которая отслеживает поведение приложений и оптимизирует их производительность, снижая потребление батареи и ресурсов.
Фоновое ограничение (Background Limits): приложения, работающие в фоновом режиме, имеют жёсткие ограничения на использование ресурсов (например, CPU и батареи).
Android 7 (Nougat):
Режим разделения экрана (Split-Screen): позволяет одновременно запускать два приложения. Быстрая смена между последними приложениями через двойное нажатие кнопки недавних задач.
Android 8 (Oreo):
Картинка в картинке (Picture-in-Picture): возможность сворачивать видео или навигационные приложения в маленькое окно, которое остается поверх других приложений.
Уведомления стали более функциональными: появились каналы уведомлений (Notification Channels), позволяющие группировать и настраивать уведомления от приложений.
Уведомления с задержкой: появилось возможность откладывать уведомления на некоторое время (Snooze).
Android 7 (Nougat):
Улучшения в системе ART (Android Runtime) позволили ускорить запуск приложений по сравнению с предыдущими версиями.
Android 8 (Oreo):
Добавлена функция Instant Apps: позволяет использовать приложения без их предварительной установки.
Приложения запускаются быстрее благодаря оптимизациям ART и сокращению кода, который нужно интерпретировать при старте.
Android 7 (Nougat):
Впервые введена функция Direct Boot, позволяющая приложениям выполнять задачи (например, будильник или приём SMS) до ввода PIN-кода.
Android 8 (Oreo):
Представлен Google Play Protect — система защиты, которая сканирует приложения на наличие вредоносного кода.
Улучшена безопасность установки приложений из сторонних источников: теперь каждое приложение требует отдельного разрешения на установку.
Укрепление работы шифрования.
Android 7 (Nougat): Поддержка новых API для работы с графикой, таких как Vulkan API для улучшения производительности в играх.
Android 8 (Oreo):
Новый формат LDAC для передачи высококачественного звука через Bluetooth (например, для беспроводных наушников).
Поддержка Wide Color Gamut для улучшения отображения цветов на экранах с расширенным динамическим диапазоном (HDR).
Android 7 (Nougat):
Уведомления стали интерактивными, добавлена возможность ответа прямо из уведомления.
Поддержка группировки уведомлений.
Android 8 (Oreo):
Каналы уведомлений: теперь можно настроить типы уведомлений, которые вы хотите получать от приложения (например, отключить уведомления о рекламных акциях, оставив только важные).
Добавлена возможность временного откладывания уведомлений (Snooze).
Android 7 (Nougat):
Поддержка многоязычия: возможность выбрать несколько языков одновременно.
Android 8 (Oreo):
Автоматическое заполнение форм (Autofill): помогает автоматически заполнять пароли и другую информацию в приложениях.
Обои адаптируются под светлую или тёмную тему интерфейса.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍2
Сервис напрямую не взаимодействует с пользователем, так как он работает в фоновом режиме.
Однако он может отправлять уведомления или использовать BroadcastReceiver для передачи информации Activity.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥1
Dalvik Virtual Machine (DVM) и Android Runtime (ART) — это две среды выполнения для запуска Android-приложений. DVM использовалась в ранних версиях Android, в то время как ART пришла на замену DVM, начиная с Android 5.0 (Lollipop). Основное различие между ними заключается в способе выполнения кода и производительности.
Dalvik Virtual Machine (DVM): Just-In-Time (JIT) компиляция
Dalvik использует JIT-компиляцию (Just-In-Time), что означает, что код приложения компилируется в машинный код во время выполнения (runtime).
Когда приложение запускается, DVM интерпретирует байт-код (.dex-файлы), а при необходимости компилирует часть кода "на лету" для повышения производительности.
Этот подход требует дополнительных ресурсов во время работы приложения, что увеличивает задержки (лаг) при запуске и потребляет больше CPU и батареи.
ART использует AOT-компиляцию (Ahead-Of-Time), которая компилирует весь код приложения в машинный код заранее — во время установки приложения.
Это устраняет необходимость интерпретации и JIT-компиляции во время работы приложения, что снижает нагрузку на процессор и улучшает производительность.
Dalvik (DVM):
Поскольку JIT-компиляция происходит во время работы приложения, это создает дополнительную нагрузку на процессор и замедляет выполнение.
Производительность ниже из-за частой интерпретации кода.
ART:
Благодаря AOT-компиляции приложения запускаются быстрее и работают плавнее.
Потребление ресурсов (CPU, батарея) значительно ниже, поскольку интерпретация и компиляция кода уже выполнены на этапе установки.
Dalvik (DVM):
Приложения запускаются медленнее, так как DVM интерпретирует код во время каждого запуска.
ART:
Приложения запускаются быстрее, так как код уже компилирован в машинный код на этапе установки.
Dalvik (DVM):
Потребляет больше батареи из-за того, что JIT-компиляция выполняется постоянно во время работы приложения.
ART:
Более энергоэффективен, так как большая часть работы выполнена заранее, и процессор не нагружается так сильно.
Dalvik (DVM):
Приложения устанавливаются быстрее, так как код не компилируется заранее.
ART:
Приложения устанавливаются медленнее, так как на этапе установки выполняется AOT-компиляция.
Например, установка приложения в ART может занимать больше времени, чем в DVM, из-за компиляции кода.
Dalvik (DVM):
DVM использует меньше памяти на устройстве, так как код компилируется только во время работы приложения, и машинный код не сохраняется.
ART:
AOT-компиляция увеличивает размер приложения, так как компилированный машинный код сохраняется на устройстве. Это требует больше места в памяти.
Dalvik (DVM):
Ограниченные возможности отладки, так как JIT-компиляция не предоставляет доступа к заранее оптимизированному коду.
ART:
ART позволяет разработчикам использовать более продвинутые инструменты отладки (например, профилирование исполнения) и лучше анализировать производительность приложений.
Dalvik (DVM):
Dalvik был изначально разработан для устройств с ограниченными ресурсами (медленные процессоры, малый объем оперативной памяти).
Приложения работали в основном в условиях ограниченного оборудования.
ART:
ART ориентирован на современные устройства с мощными процессорами и большим объемом памяти.
Он лучше справляется с современными требованиями приложений.
- Установка быстрая.
- При запуске приложения DVM интерпретирует и компилирует код. Это требует времени и ресурсов.
- Приложение может работать медленно из-за интерпретации кода в реальном времени.
- Установка занимает больше времени, так как код компилируется сразу.
- Запуск приложения быстрый, потому что код уже готов к исполнению.
- Приложение работает плавно, так как отсутствует необходимость компиляции во время выполнения.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤3
1. Это позволяет сервису работать как foreground, обеспечивая его приоритетное выполнение.
2. Но такие действия требуют отображения уведомлений, что может раздражать пользователей.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6
Переход от списка (например, списка элементов в
RecyclerView) к экрану деталей элемента в Android является очень распространённой задачей. Для реализации таких переходов используются Intent, Bundle, ViewModel, а также инструменты навигации, такие как Navigation Component.Это базовый способ передачи данных от одного экрана (активности) к другому.
1. При нажатии на элемент списка (
RecyclerView) создается Intent.2. В
Intent передаются данные (например, ID элемента или вся информация в виде Parcelable или Serializable объекта).3. Новый экран (деталка) запускается с помощью метода
startActivity(intent).4. На экране детализации данные извлекаются из
Intent.// Предположим, что в адаптере RecyclerView вы обрабатываете клик на элементе
val intent = Intent(this, DetailActivity::class.java)
// Передаем ID элемента через Intent
intent.putExtra("ITEM_ID", item.id)
startActivity(intent)
Деталка (DetailActivity)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_detail)
// Получаем данные из Intent
val itemId = intent.getIntExtra("ITEM_ID", -1)
// Используем itemId, чтобы загрузить данные о выбранном элементе
loadItemDetails(itemId)
}
fun loadItemDetails(id: Int) {
// Например, загрузка из базы данных или сети
}Navigation Component — это современный способ управления переходами между экранами в Android. Он значительно упрощает реализацию навигации и передачи данных.
1. Вы создаете граф навигации (
nav_graph), где определяете все экраны (фрагменты) и связи между ними.2. Переходы между экранами задаются как действия (actions) внутри графа.
3. Данные передаются через аргументы (arguments), которые указываются в
nav_graph.nav_graph (res/navigation/nav_graph.xml)<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="https://schemas.android.com/apk/res/android"
app:startDestination="@id/listFragment">
<fragment
android:id="@+id/listFragment"
android:name="com.example.ListFragment"
android:label="Список" >
<action
android:id="@+id/action_listFragment_to_detailFragment"
app:destination="@id/detailFragment" />
</fragment>
<fragment
android:id="@+id/detailFragment"
android:name="com.example.DetailFragment"
android:label="Детали" >
<argument
android:name="itemId"
app:argType="integer" />
</fragment>
</navigation>
val action = ListFragmentDirections.actionListFragmentToDetailFragment(itemId = 123)
findNavController().navigate(action)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Получаем аргумент, переданный через Navigation Component
val itemId = arguments?.getInt("itemId") ?: -1
// Используем itemId для загрузки деталей
loadItemDetails(itemId)
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
1. Android блокирует запуск долгоживущих сервисов в фоне на новых версиях, чтобы избежать утечек памяти и энергозатрат.
2. Для обхода ограничений используют WorkManager или foreground-сервисы.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥2
Самый обычный сервис, который наследуется от класса
Service, по умолчанию запускается в главном потоке приложения, который также называется UI-потоком (User Interface Thread). Это означает, что все операции, выполняемые в сервисе, включая методы onStartCommand(), onCreate(), и onBind(), выполняются в главном потоке. Если в сервисе будут выполняться длительные или ресурсоемкие операции, такие как сетевые запросы, обработка больших данных или выполнение сложных вычислений, это может привести к "зависанию" пользовательского интерфейса и появлению сообщений о том, что приложение не отвечает (ANR — Application Not Responding).Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
1. Также можно применить WorkManager для длительных задач с учётом энергопотребления.
2. Для задач, требующих сетевого подключения, применяйте JobScheduler.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5
Когда используется deeplink, может возникнуть проблема, что одно и то же Activity может быть открыто несколько раз в стеке задач. Это происходит, если приложение запускается из внешнего источника (например, из браузера или другого приложения), и Android создает новую задачу или новую копию Activity вместо использования уже существующей. Чтобы справиться с этим, нужно правильно настроить
launchMode, интенты и флаги.При запуске приложения через deep link, система Android может:
1. Создать новый экземпляр вашего Activity (даже если оно уже существует в стеке задач).
2. Поместить новую задачу в стек задач.
Если это не контролировать, пользователь может увидеть много дубликатов одного и того же Activity, что плохо для UX и может вызвать утечку памяти.
В файле
AndroidManifest.xml можно настроить поведение Activity с помощью атрибута launchMode:singleTop: Если Activity уже находится на вершине стека, система не будет создавать новый экземпляр.singleTask: Убедитесь, что только один экземпляр Activity существует в задаче. Если Activity уже существует, система передаст интент в метод onNewIntent().singleInstance: Подходит для случаев, когда Activity должно быть абсолютно уникальным (используется редко).<activity
android:name=".MyActivity"
android:launchMode="singleTop" />
Если вы используете deep link или запускаете Activity вручную, можно добавить флаги, чтобы управлять созданием экземпляров:
val intent = Intent(this, MyActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
startActivity(intent)
Если используется
singleTop или singleTask, система вызывает метод onNewIntent(Intent intent) вместо создания нового экземпляра Activity. Этот метод можно переопределить для обработки новых данных из интента override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
// Обработка нового интента
val data = intent?.data
// Используйте данные deeplink
}
Если требуется, чтобы разные deep link открывали одну и ту же задачу, можно настроить
taskAffinity. Это нужно реже, но полезно, если нужно обрабатывать ссылки с разными контекстами.Дополнительно можно вручную проверять, существует ли нужное Activity в текущем состоянии приложения, например, используя LiveData или ViewModel.
Файл
AndroidManifest.xml<activity
android:name=".MyActivity"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="example.com"
android:path="/deeplink" />
</intent-filter>
</activity>
Файл
MyActivity.ktclass MyActivity : AppCompatActivity() {
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
// Обработка данных из нового интента (deeplink)
val uri = intent?.data
uri?.let {
// Например, получить параметры из ссылки
val param = it.getQueryParameter("id")
Log.d("Deeplink", "Parameter id: $param")
}
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
2. Парсинг данных, например, с использованием Jsoup или SAXParser.
3. Сохранение и обновление данных локально (Room или SharedPreferences).
4. Организация списка лент с возможностью фильтрации и уведомлений об обновлениях.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2🎉1
Проблемы с элементами списка в Android-приложениях могут быть разнообразными. Давайте рассмотрим некоторые из наиболее распространённых проблем и способы их решения.
// Пример использования Glide для загрузки изображений
Glide.with(context)
.load(imageUrl)
.into(imageView)
class MyAdapter(private val itemList: List<Item>) : RecyclerView.Adapter<MyAdapter.ViewHolder>() {
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val textView: TextView = itemView.findViewById(R.id.textView)
val imageView: ImageView = itemView.findViewById(R.id.imageView)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_layout, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = itemList[position]
holder.textView.text = item.text
Glide.with(holder.itemView.context).load(item.imageUrl).into(holder.imageView)
}
override fun getItemCount() = itemList.size
} class ItemDiffCallback : DiffUtil.ItemCallback<Item>() {
override fun areItemsTheSame(oldItem: Item, newItem: Item): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: Item, newItem: Item): Boolean {
return oldItem == newItem
}
}
// Использование в адаптере
val diffCallback = ItemDiffCallback()
val diffResult = DiffUtil.calculateDiff(diffCallback)
diffResult.dispatchUpdatesTo(myAdapter)val liveData = MutableLiveData<List<Item>>()
liveData.observe(viewLifecycleOwner, Observer { items ->
myAdapter.submitList(items)
})
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3😁2
2. Интеграция ComposeView: для использования Compose внутри существующих ViewGroup.
3. Модульная миграция: разделение приложения на модули и обновление каждого модуля поэтапно.
4. Тестирование на каждом этапе, чтобы избежать регрессий.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥1
В Retrofit, чтобы передать значение в определенное место URL-адреса для GET-запроса, нужно использовать аннотацию
@Path. Эта аннотация позволяет заменить параметр в строке пути на значение, переданное в метод.1. Внутри аннотации
@GET вы указываете строку пути, содержащую плейсхолдеры в фигурных скобках ({}).2. Аннотация
@Path связывает переменную метода с плейсхолдером в URL.3. Когда метод вызывается, значение переменной подставляется вместо плейсхолдера в URL.
Допустим, у вас есть API с эндпоинтом
https://api.example.com/users/{id}/detailsНастраиваем интерфейс Retrofit
interface ApiService {
@GET("users/{id}/details")
suspend fun getUserDetails(
@Path("id") userId: String
): Response<UserDetails>
}Теперь, когда вы вызываете этот метод, вы можете передать значение для
id, и Retrofit автоматически подставит его в URLval apiService = retrofit.create(ApiService::class.java)
suspend fun fetchUserDetails() {
val userId = "123" // Пример значения
val response = apiService.getUserDetails(userId)
if (response.isSuccessful) {
println("User details: ${response.body()}")
} else {
println("Error: ${response.errorBody()?.string()}")
}
}
Вы можете использовать несколько плейсхолдеров в пути и связать их с несколькими параметрами с помощью
@Path. Например:API-эндпоинт
https://api.example.com/users/{userId}/posts/{postId}Интерфейс Retrofit
interface ApiService {
@GET("users/{userId}/posts/{postId}")
suspend fun getPostDetails(
@Path("userId") userId: String,
@Path("postId") postId: String
): Response<PostDetails>
}Вызов метода
val response = apiService.getPostDetails("123", "456")
// URL: https://api.example.com/users/123/posts/456Если вы передаете
null или пустую строку в @Path, это вызовет ошибку, так как Retrofit требует обязательного значения для всех параметров пути. Убедитесь, что передаваемое значение всегда валидно.Если значение пути может содержать символы, требующие экранирования (например, пробелы, специальные символы), Retrofit автоматически обработает это с помощью кодировки URL. Это делает использование
@Path безопасным.@GET("search/{query}")
suspend fun search(
@Path("query") searchQuery: String
): Response<SearchResults>Если вы вызовете метод с поисковым запросом
apiService.search("hello world!")
// Retrofit закодирует URL: https://api.example.com/search/hello%20world%21Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6