Контекст (Context) предоставляет доступ к системным ресурсам и функциям:
- доступ к Resources, Assets,
- запуск Activity, Service,
- доступ к SharedPreferences,
- получение SystemService.
Это один из ключевых элементов Android, передающий «среду выполнения».
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
ArrayList реализован на основе массива. Амортизированное O(1). Если массив не заполнен, элемент добавляется в конец списка. В случае, если массив заполнен, требуется выделение нового массива и копирование элементов, что занимает O(n) времени.
val arrayList = ArrayList<Int>()
arrayList.add(1) // Быстрая вставка в конец
O(n). Необходимо сдвинуть все элементы, начиная с позиции вставки, чтобы освободить место для нового элемента. Это требует времени, пропорционального количеству элементов после позиции вставки.
arrayList.add(0, 2) // Медленная вставка в начало
arrayList.add(1, 3) // Медленная вставка в середину
LinkedList реализован на основе узлов, где каждый узел содержит ссылку на следующий и/или предыдущий узел (в случае двусвязного списка).val linkedList = LinkedList<Int>()
linkedList.addFirst(1) // Быстрая вставка в начало
O(1) (если есть ссылка на последний узел) или O(n) (если необходимо пройти весь список). Если список двусвязный и хранится ссылка на последний элемент, вставка в конец осуществляется за O(1). В противном случае, требуется пройти весь список до конца.
linkedList.addLast(2) // Быстрая вставка в конец, если есть ссылка на последний узел
O(n). Необходимо пройти список до нужной позиции и изменить ссылки узлов.
linkedList.add(1, 3) // Медленная вставка в середину
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Nested class — статический, не имеет доступа к экземпляру внешнего класса.
Inner class — нестатический, может обращаться к полям и методам внешнего класса, включая приватные.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6
Использует комбинацию слабых ссылок (
WeakReference), анализ кучи и цепочек удержания, чтобы найти ссылки на уничтоженные Activity или другие объекты, которые должны были быть освобождены сборщиком мусора. Вот более подробное объяснение того, как это работает:Когда Activity (или другой компонент) уничтожается, LeakCanary создает слабую ссылку на этот объект.
val weakReference = WeakReference(activity)
LeakCanary инициирует сборку мусора, чтобы попытаться освободить уничтоженный объект.
System.gc()
System.runFinalization()
LeakCanary проверяет, освобождена ли слабая ссылка. Если объект не был освобожден, это указывает на возможную утечку памяти.
if (weakReference.get() != null) {
// Объект все еще удерживается в памяти, вероятна утечка
}Если слабая ссылка не была освобождена, LeakCanary создает снимок кучи (heap dump) для дальнейшего анализа.
val heapDumpFile = createHeapDump()
LeakCanary использует библиотеку Shark для анализа снимка кучи. Shark проверяет все объекты в куче и их удерживающие ссылки.
val heapAnalyzer = HeapAnalyzer()
val analysis = heapAnalyzer.analyze(heapDumpFile)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥1
object в Kotlin создаёт singleton — единственный экземпляр. Нельзя создавать новые экземпляры, он инициализируется при первом обращении.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
В Kotlin оператор
== используется для структурного сравнения объектов. Оператор
== вызывает метод equals(), чтобы проверить содержимое объектов, а не их ссылки. data class User(val name: String)
fun main() {
val user1 = User("Alice")
val user2 = User("Alice")
println(user1 == user2) // true (структурное сравнение)
println(user1 === user2) // false (сравнение ссылок)
}
== проверяет, равны ли данные объектов (equals()). === проверяет, ссылаются ли объекты на один и тот же участок памяти. val str1 = "Hello"
val str2 = "Hello"
println(str1 == str2) // true (содержимое одинаковое)
println(str1 === str2) // true (Kotlin кеширует строки)
val obj1 = String("Hello".toCharArray())
val obj2 = String("Hello".toCharArray())
println(obj1 == obj2) // true (содержимое одинаковое)
println(obj1 === obj2) // false (разные объекты в памяти)
Если
equals() не переопределён, то сравниваются ссылки (как ===). class Person(val name: String)
fun main() {
val p1 = Person("Bob")
val p2 = Person("Bob")
println(p1 == p2) // false (equals() не переопределён, сравниваются ссылки)
}
Чтобы
== работал по содержимому, нужно переопределить equals()class Person(val name: String) {
override fun equals(other: Any?): Boolean {
return other is Person && other.name == this.name
}
}
fun main() {
val p1 = Person("Bob")
val p2 = Person("Bob")
println(p1 == p2) // true (equals() сравнивает содержимое)
}Kotlin предотвращает
NullPointerException при сравнении с null:val a: String? = null
val b: String? = "Hello"
println(a == b) // false (без NPE)
println(a == null) // true
Когда
a == b, на самом деле выполняется:a?.equals(b) ?: (b === null)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Hilt предоставляет компоненты для приложения, активностей, фрагментов, ViewModel и других уровней. Модуль подключается с помощью аннотации
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
Самый обычный сервис, который наследуется от класса
Service, по умолчанию запускается в главном потоке приложения, который также называется UI-потоком (User Interface Thread). Это означает, что все операции, выполняемые в сервисе, включая методы onStartCommand(), onCreate(), и onBind(), выполняются в главном потоке. Если в сервисе будут выполняться длительные или ресурсоемкие операции, такие как сетевые запросы, обработка больших данных или выполнение сложных вычислений, это может привести к "зависанию" пользовательского интерфейса и появлению сообщений о том, что приложение не отвечает (ANR — Application Not Responding).Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
- Composable функции: описывают UI.
- State: управляет состоянием компонентов.
- Modifiers: применяются для настройки внешнего вида и поведения.
- Layouts: определяют структуру расположения элементов на экране.
- Recomposition: механизм обновления интерфейса при изменении состояния.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6👍1
В Android есть несколько способов навигации между экранами. Давай разберём основные.
Каждый экран – это отдельная
Activity, переход осуществляется с помощью Intent. val intent = Intent(this, SecondActivity::class.java)
startActivity(intent)
Один
Activity содержит несколько Fragment, навигация через FragmentManager. supportFragmentManager.beginTransaction()
.replace(R.id.container, SecondFragment())
.addToBackStack(null)
.commit()
Google рекомендует
Navigation Component для удобной работы с Fragment. findNavController().navigate(R.id.action_firstFragment_to_secondFragment)
Используется
BottomNavigationView или TabLayout для переключения между экранами. bottomNavigationView.setOnNavigationItemSelectedListener { item ->
when (item.itemId) {
R.id.home -> replaceFragment(HomeFragment())
R.id.profile -> replaceFragment(ProfileFragment())
}
true
}Боковое меню (
DrawerLayout) с пунктами навигации. drawerLayout.openDrawer(GravityCompat.START)
Навигация через ссылки (например,
myapp://profile/123). <intent-filter>
<action android:name="android.intent.action.VIEW"/>
<data android:scheme="myapp" android:host="profile"/>
</intent-filter>
Используется
NavHost и NavController. NavHost(navController, startDestination = "home") {
composable("home") { HomeScreen(navController) }
composable("profile") { ProfileScreen(navController) }
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6👍1
Да! В Android есть специальные Map-коллекции, которые позволяют хранить примитивные типы (
int, long, boolean и т. д.) без автоупаковки (autoboxing). Обычные
HashMap<Int, Int> в Kotlin используют автоупаковку (Integer вместо int), что: Увеличивает потребление памяти (из-за объектов
Integer, Long и т. д.). Замедляет работу (из-за ненужного создания объектов).
Решение? Использовать специализированные мэпы из
android.util! Хранит пары
Int → Any, но без автоупаковки. import android.util.SparseArray
val sparseArray = SparseArray<String>()
sparseArray.put(1, "Привет")
sparseArray.put(2, "Мир")
println(sparseArray[1]) // Привет
println(sparseArray[2]) // Мир
Хранит пары
Int → Int без автоупаковки. import android.util.SparseIntArray
val sparseIntArray = SparseIntArray()
sparseIntArray.put(1, 100)
sparseIntArray.put(2, 200)
println(sparseIntArray[1]) // 100
println(sparseIntArray[2]) // 200
Оптимизирован для
Int → Boolean пар. import android.util.SparseBooleanArray
val sparseBooleanArray = SparseBooleanArray()
sparseBooleanArray.put(1, true)
sparseBooleanArray.put(2, false)
println(sparseBooleanArray[1]) // true
println(sparseBooleanArray[2]) // false
Оптимизирован для
Long → Any?, аналог SparseArray, но с Long ключами. import android.util.LongSparseArray
val longSparseArray = LongSparseArray<String>()
longSparseArray.put(10000000000L, "Длинный ключ")
println(longSparseArray[10000000000L]) // Длинный ключ
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
PendingIntent — это обёртка над Intent, позволяющая другим компонентам (например, системным) выполнить Intent от имени вашего приложения, даже если оно сейчас не активно.
Используется:
- В уведомлениях (NotificationManager).
- Для запуска BroadcastReceiver или Service.
- В AlarmManager.
Он играет роль разрешения: система может отложить выполнение кода, но с уже подтверждёнными правами.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4
Этот инструмент показывает время, затраченное на отрисовку каждого кадра. Использование этого инструмента позволяет выявить "тяжелые" кадры и измерить улучшения после оптимизации.
Предоставляет набор инструментов для анализа производительности приложения.
Создание и использование тестов производительности помогает количественно оценить улучшения. Вы можете использовать библиотеку Jetpack Benchmark для создания и выполнения тестов производительности.
build.gradle:dependencies {
androidTestImplementation "androidx.benchmark:benchmark-junit4:1.1.0"
androidTestImplementation "androidx.test:runner:1.3.0"
androidTestImplementation "androidx.test:rules:1.3.0"
}import androidx.benchmark.junit4.BenchmarkRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class ExampleBenchmark {
@get:Rule
val benchmarkRule = BenchmarkRule()
@Test
fun myFunctionBenchmark() {
benchmarkRule.measureRepeated {
// Вызов вашей функции или кода для тестирования производительности
myFunction()
}
}
}
Используйте журналирование для измерения времени выполнения определенных операций.
val startTime = System.currentTimeMillis()
// Ваш код
val endTime = System.currentTimeMillis()
Log.d("Performance", "Время выполнения: ${endTime - startTime} мс")
StrictMode помогает обнаружить операции, которые могут замедлить работу приложения, такие как работа с сетью или базой данных в главном потоке.
if (BuildConfig.DEBUG) {
StrictMode.setThreadPolicy(
StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyLog()
.build()
)
StrictMode.setVmPolicy(
StrictMode.VmPolicy.Builder()
.detectAll()
.penaltyLog()
.build()
)
}Systrace позволяет собирать и анализировать трассировки производительности системы, предоставляя детализированные данные о времени выполнения различных операций.
adb shell am broadcast -a com.android.systemui.screenshot.ScreenshotService.ACTION_SYSTRACE.Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8👍3
По умолчанию нельзя, потому что дженерики стираются (
Type Erasure) во время компиляции. fun <T> printType(value: T) {
println(T::class.simpleName) // ❌ Ошибка! Нельзя использовать `T::class`
}Если используем
inline fun, можно сделать дженерик "реальным" (reified). inline fun <reified T> printType(value: T) {
println(T::class.simpleName) // ✅ Работает!
}
fun main() {
printType(123) // Int
printType("Hello") // String
printType(3.14) // Double
}Если дженерик используется в классе, то
reified не поможет. class MyGenericClass<T>(private val type: KClass<T>) {
fun printType() {
println(type.simpleName) // ✅ Работает
}
}
fun main() {
val obj = MyGenericClass(String::class)
obj.printType() // String
}Для сложных дженериков (
List<T>, Map<K, V>) используем typeOf<T>() (только с reified). import kotlin.reflect.typeOf
inline fun <reified T> printGenericType() {
val type = typeOf<T>()
println(type) // ✅ List<Int>, Map<String, Boolean> и т. д.
}
fun main() {
printGenericType<List<Int>>() // kotlin.collections.List<kotlin.Int>
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
– drawable/ — изображения,
– layout/ — xml-макеты,
– values/ — строки, цвета, стили, размеры,
– raw/, assets/ — аудио, видео, JSON и прочее.
Хранятся данные, не изменяемые во время выполнения.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1
Класс-наследник в Kotlin получает доступ к функционалу родительского класса через:
Наследование (
:) — доступ ко всем open методам и свойствам. Ключевое слово
super — вызов методов родителя. Переопределение (
override) — изменение поведения. Класс-наследник получает доступ ко всем
open методам и свойствам родителя. open class Animal(val name: String) {
fun eat() {
println("$name ест")
}
}
class Dog(name: String) : Animal(name)
fun main() {
val dog = Dog("Шарик")
dog.eat() // Шарик ест (метод унаследован)
}Пример
open class Animal {
open fun makeSound() {
println("Животное издаёт звук")
}
}
class Dog : Animal() {
override fun makeSound() {
super.makeSound() // Вызываем метод родителя
println("Гав-гав!")
}
}
fun main() {
val dog = Dog()
dog.makeSound()
}Вывод
Животное издаёт звук
Гав-гав!
Класс-наследник может изменить поведение родительского метода.
open class Animal {
open fun move() {
println("Животное двигается")
}
}
class Bird : Animal() {
override fun move() {
println("Птица летит") // Переопределяем метод
}
}
fun main() {
val bird = Bird()
bird.move() // Птица летит
}Пример
open class Animal(val name: String)
class Dog(name: String, val breed: String) : Animal(name) {
fun info() {
println("Имя: $name, Порода: $breed") // Используем `name` из родителя
}
}
fun main() {
val dog = Dog("Бобик", "Лабрадор")
dog.info() // Имя: Бобик, Порода: Лабрадор
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
1. dispatchTouchEvent() — распределяет событие.
2. onTouchEvent() — обрабатывает вью, если не перехвачено.
3. onClick() — вызывается, если был ACTION_UP без движения.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3
XML — это eXtensible Markup Language (Расширяемый язык разметки).
eXtensible → Расширяемый (можно создавать свои теги).
Markup → Разметка (использует теги
<tag> для структурирования данных). Language → Язык (формат хранения и передачи данных).
В Android:
Разметка UI (
activity_main.xml). Конфигурация (
AndroidManifest.xml). Ресурсы (
strings.xml, colors.xml). В веб-разработке:
Конфигурации (
.xml файлы в серверных приложениях). Форматы обмена данными (SOAP, RSS, SVG).
Пример XML-кода
<user>
<name>Алиса</name>
<age>25</age>
</user>
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Java: byte, short, int, long, float, double, char, boolean.
Kotlin использует обёртки (Int, Double, Boolean и др.), которые компилируются в примитивы при необходимости.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1