HTTP-запрос (GET и POST) в Kotlin для Android
Добавьте зависимости
В файле build.gradle (Module: app) добавьте следующие зависимости:
dependencies {
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0' // Для работы с JSON
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
implementation 'com.google.code.gson:gson:2.10.1'
}
Создайте модель данных
package com.coop.myapplication1.retrofit
data class Product(
val id: Int,
val device_id: String,
val name: String,
val last_seen: String,
val is_active: Boolean
)
Определите API-интерфейс
Создайте интерфейс для описания запросов:
package com.coop.myapplication1.retrofit
import retrofit2.http.GET
import retrofit2.http.Path
interface ProductApi {
@GET("device/{id}")
suspend fun getProductById(@Path("id") id: Int): Product
}
В Main добавим следующий код:
val retrofit = Retrofit.Builder().baseUrl("http://192.168.50.70:8000/api/")
.addConverterFactory(GsonConverterFactory.create()).build()
val productApi = retrofit.create(ProductApi::class.java)
val btn = findViewById<Button>(R.id.button2)
var result = findViewById<TextView>(R.id.textView2)
btn.setOnClickListener {
CoroutineScope(Dispatchers.IO).launch {
try {
val product = productApi.getProductById(1)
runOnUiThread {
result.text = product?.name ?: "Product not found"
}
} catch (e: Exception) {
runOnUiThread {
result.text = "Error: ${e.message}"
}
}
}
}
Для современных версий Android (API 23+) при использовании HTTP (а не HTTPS) может потребоваться дополнительная настройка для разрешения небезопасных соединений, так как ваш код использует http://192.168.50.70:8000/api/. Для этого нужно:
Создать файл res/xml/network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">192.168.50.70</domain>
</domain-config>
</network-security-config>
Итоговый манифест с этой настройкой будет выглядеть так:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyApplication1"
android:networkSecurityConfig="@xml/network_security_config"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
View Binding
Как подключить View Binding
В файле build.gradle (уровень модуля) добавьте:
groovy
android {
...
buildFeatures {
viewBinding = true
}
}
В MainActivity вы подключаете View Binding так:
kotlin
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.example.myapp.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// Доступ к элементам
binding.textView.text = "View Binding работает!"
binding.button.setOnClickListener {
binding.textView.text = "Кнопка нажата!"
}
}
}
SharedPreferences
import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
private val PREFS_NAME = "MyPrefs"
private val KEY_USERNAME = "username"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Получение SharedPreferences
val prefs = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
val editor = prefs.edit()
// Сохранение данных
editor.putString(KEY_USERNAME, "Иван")
editor.apply() // Асинхронно сохраняет данные
// Чтение данных
val username = prefs.getString(KEY_USERNAME, "Гость") // "Гость" — значение по умолчанию
println("Имя пользователя: $username")
}
}
При наличии конфликта классов:
configurations.all {
exclude(group = "com.intellij", module = "annotations")
}
Room Database
gradle
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
id("kotlin-kapt")
}
dependencies {
kapt(libs.androidx.room.compiler)
implementation(libs.androidx.room.ktx)
}
Модель данных (Entity):
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "tasks")
data class Task(
@PrimaryKey(autoGenerate = true) val id: Int = 0,
val title: String,
val isCompleted: Boolean
)
DAO (Data Access Object):
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
@Dao
interface TaskDao {
@Insert
suspend fun insert(task: Task)
@Query("SELECT * FROM tasks")
suspend fun getAllTasks(): List<Task>
@Query("DELETE FROM tasks WHERE id = :taskId")
suspend fun deleteById(taskId: Int)
}
База данных:
import androidx.room.Database
import androidx.room.RoomDatabase
@Database(entities = [Task::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun taskDao(): TaskDao
}
Main
var db = Room.databaseBuilder(
applicationContext,
AppDatabase::class.java,
"task_database"
).build()
btn.setOnClickListener {
CoroutineScope(Dispatchers.IO).launch {
val taskDao = db.taskDao()
// Добавление задачи
taskDao.insert(Task(title = "Купить молоко", isCompleted = false))
// Получение всех задач
val tasks = taskDao.getAllTasks()
// Переход на главный поток
launch(Dispatchers.Main) {
res.text = tasks.joinToString("\n") { it.toString() }
}
}
}
Работа с JSON
implementation 'com.google.code.gson:gson:2.10.1'
Пример JSON
json
{
"id": 1,
"name": "Иван",
"age": 25
}
Модель данных:
kotlin
data class User(
val id: Int,
val name: String,
val age: Int
)
Парсинг:
kotlin
import com.google.gson.Gson
val json = """{"id": 1, "name": "Иван", "age": 25}"""
val gson = Gson()
val user = gson.fromJson(json, User::class.java)
println("Пользователь: ${user.name}, возраст: ${user.age}")
// Сериализация обратно в JSON
val jsonString = gson.toJson(user)
println("JSON: $jsonString")