Цена за 48 часов в ленте | 2100,00 |
Цена за 1 час закрепления | N/A |
Взаимопиар | Нет |
Activity
. Context
или получают его через getContext()
. Activity
и Service
наследуют Context
. Fragment
, BroadcastReceiver
и ContentProvider
получают Context
через getContext()
. fun showToast(context: Context) {
Toast.makeText(context, "Привет!", Toast.LENGTH_SHORT).show()
}
AndroidManifest.xml
, чтобы система знала о них. Intent
. Пример: Запуск `Activity` из `Service` через `Intent`val intent = Intent(context, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)
data class
могут возникнуть проблемы со списками при использовании: copy()
– список не копируется, а передаётся по ссылке. equals()
и hashCode()
– List
сравнивается по элементам, что может быть медленно. MutableList
) – изменения внутри списка изменяют все копии объекта. data class User(val name: String, val tags: List)
fun main() {
val original = User("Alice", listOf("Admin", "Editor"))
val copy = original.copy() // ✅ Поверхностное копирование
println(original.tags === copy.tags) // true (один и тот же объект)
}
toList()
, чтобы создать новый неизменяемый список: fun main() {
val original = User("Alice", listOf("Admin", "Editor"))
val copy = original.copy(tags = original.tags.toList())
println(original.tags === copy.tags) // false (разные объекты)
}
data class Message(val id: Int, val content: String, val tags: List)
fun main() {
val message1 = Message(1, "Привет", listOf("important", "urgent"))
val message2 = Message(1, "Привет", listOf("important", "urgent"))
println(message1 == message2) // true (сравнивает элементы списка)
}
id
) уникален, сравнивать только его data class Message(val id: Int, val content: String, val tags: List) {
override fun equals(other: Any?) = other is Message && this.id == other.id
override fun hashCode() = id.hashCode()
}
data class Task(val name: String, val subtasks: MutableList)
fun main() {
val original = Task("Купить продукты", mutableListOf("Хлеб", "Молоко"))
val copy = original.copy() // ✅ Поверхностная копия
copy.subtasks.add("Яйца") // ❌ Меняет список в обоих объектах!
println(original.subtasks) // [Хлеб, Молоко, Яйца]
println(copy.subtasks) // [Хлеб, Молоко, Яйца]
}
MutableList
внутри copy()
data class Task(val name: String, val subtasks: List) {
fun deepCopy() = Task(name, subtasks.toMutableList())
}
fun main() {
val original = Task("Купить продукты", mutableListOf("Хлеб", "Молоко"))
val copy = original.deepCopy()
copy.subtasks.toMutableList().add("Яйца") // ✅ Теперь изменения не влияют на оригинал
println(original.subtasks) // [Хлеб, Молоко]
println(copy.subtasks) // [Хлеб, Молоко, Яйца]
}
Activity
) class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val button = findViewById(R.id.button)
button.setOnClickListener {
val result = fetchData() // ❌ Логика в UI
button.text = result
}
}
fun fetchData(): String {
return "Данные с сервера" // ❌ Тут должна быть ViewModel
}
}
Activity
+ ViewModel
MainActivity
(только UI) class MainActivity : AppCompatActivity() {
private val viewModel: MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val button = findViewById(R.id.button)
viewModel.text.observe(this) { text ->
button.text = text // ✅ UI обновляется из ViewModel
}
button.setOnClickListener {
viewModel.loadData() // ✅ Вызываем бизнес-логику
}
}
}
MainViewModel
(бизнес-логика) class MainViewModel : ViewModel() {
private val _text = MutableLiveData()
val text: LiveData = _text
fun loadData() {
_text.value = "Данные с сервера" // ✅ UI не знает, откуда данные
}
}
AndroidManifest.xml
, чтобы: uses-permission
, uses-feature
) для конкретного модуля. Activity
, Service
, BroadcastReceiver
) для каждого модуля. AndroidManifest.xml
главного (app
) модуля. merge
) все AndroidManifest.xml
в один итоговый файл. app/
├── src/main/AndroidManifest.xml ← Главный манифест
├── java/com/example/MainActivity.kt
├── res/
├── build.gradle
feature_login/
├── src/main/AndroidManifest.xml ← Манифест модуля `login`
├── java/com/example/login/LoginActivity.kt
├── res/
├── build.gradle
feature_chat/
├── src/main/AndroidManifest.xml ← Манифест модуля `chat`
├── java/com/example/chat/ChatActivity.kt
├── res/
├── build.gradle
feature_login
(feature_login/src/main/AndroidManifest.xml
) feature_chat
(feature_chat/src/main/AndroidManifest.xml
) AndroidManifest.xml
выглядит так camera
требует CAMERA
, но другие модули — нет. LoginActivity
в feature_login
). feature_map
использует Google Maps, но feature_login
— нет. debug build
). debug
-версии в Android Studio: gradlew assembleDebug
adb install app-unsigned.apk
Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES]
apksigner sign --ks my-release-key.jks --out app-signed.apk app-unsigned.apk