← Назад к вопросам

Какие знаешь способы работы с сетью?

2.0 Middle🔥 161 комментариев
#Сетевое взаимодействие

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Способы работы с сетью в Android

Есть несколько библиотек и подходов для сетевых запросов.

1. HttpURLConnection (встроено)

fun fetchDataBlocking(): String {
    val url = URL("https://api.example.com/users")
    val connection = (url.openConnection() as HttpURLConnection).apply {
        requestMethod = "GET"
        connectTimeout = 5000
        readTimeout = 5000
    }
    
    return connection.inputStream.bufferedReader().use { it.readText() }
}

2. OkHttp (рекомендуется)

val client = OkHttpClient.Builder()
    .connectTimeout(10, TimeUnit.SECONDS)
    .readTimeout(10, TimeUnit.SECONDS)
    .build()

val request = Request.Builder()
    .url("https://api.example.com/users")
    .get()
    .build()

val response = client.newCall(request).execute()
val body = response.body?.string()

3. Retrofit (OkHttp + JSON)

interface ApiService {
    @GET("/users")
    suspend fun getUsers(): List<User>
    
    @GET("/users/{id}")
    suspend fun getUser(@Path("id") userId: String): User
    
    @POST("/users")
    suspend fun createUser(@Body user: User): User
    
    @PUT("/users/{id}")
    suspend fun updateUser(@Path("id") userId: String, @Body user: User): User
    
    @DELETE("/users/{id}")
    suspend fun deleteUser(@Path("id") userId: String)
}

// Инициализация
val retrofit = Retrofit.Builder()
    .baseUrl("https://api.example.com")
    .addConverterFactory(GsonConverterFactory.create())
    .build()

val apiService = retrofit.create(ApiService::class.java)

// Использование
viewModelScope.launch {
    try {
        val users = apiService.getUsers()
        _users.value = users
    } catch (e: Exception) {
        _error.value = e.message
    }
}

4. Ktor Client

val httpClient = HttpClient {
    install(JsonFeature) {
        serializer = KotlinxSerializer()
    }
}

val response = httpClient.get<List<User>>("https://api.example.com/users")

// В корутине
val users = withContext(Dispatchers.IO) {
    httpClient.get("https://api.example.com/users")
}

5. HttpClient + Coroutines

class UserRepository(private val apiService: ApiService) {
    suspend fun getUser(userId: String): User = withContext(Dispatchers.IO) {
        apiService.getUser(userId)
    }
    
    fun getUserFlow(userId: String): Flow<User> = flow {
        emit(apiService.getUser(userId))
    }.flowOn(Dispatchers.IO)
}

// Использование
viewModelScope.launch {
    repository.getUserFlow("123").collect { user ->
        _user.value = user
    }
}

6. WebSocket (двусторонняя коммуникация)

interface WebSocketListener {
    fun onMessage(message: String)
    fun onError(error: Throwable)
}

val webSocket = okHttpClient.newWebSocket(
    Request.Builder().url("wss://echo.websocket.org/").build(),
    object : WebSocketListener() {
        override fun onMessage(webSocket: WebSocket, text: String) {
            println("Message: $text")
        }
        
        override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
            println("Error: $t")
        }
    }
)

webSocket.send("Hello")
webSocket.close(1000, "Goodbye")

7. Interceptor для логирования

val client = OkHttpClient.Builder()
    .addInterceptor { chain ->
        val request = chain.request()
        println("Request: ${request.url}")
        
        val response = chain.proceed(request)
        println("Response: ${response.code}")
        response
    }
    .build()

8. Обработка ошибок

class SafeApiCall<T> {
    suspend fun execute(call: suspend () -> T): Result<T> {
        return try {
            Result.Success(call())
        } catch (e: HttpException) {
            Result.Error(e.code(), e.message())
        } catch (e: IOException) {
            Result.NetworkError(e.message)
        } catch (e: Exception) {
            Result.UnknownError(e)
        }
    }
}

sealed class Result<T> {
    data class Success<T>(val data: T) : Result<T>()
    data class Error<T>(val code: Int, val message: String?) : Result<T>()
    data class NetworkError<T>(val message: String?) : Result<T>()
    data class UnknownError<T>(val exception: Exception) : Result<T>()
}

9. Параллельные запросы

val user = async { apiService.getUser("123") }
val posts = async { apiService.getPosts("123") }
val comments = async { apiService.getComments("123") }

val result = UserProfile(
    user = user.await(),
    posts = posts.await(),
    comments = comments.await()
)

10. Кеширование ответов

val cacheControl = CacheControl.Builder()
    .maxAge(1, TimeUnit.HOURS)
    .build()

val request = Request.Builder()
    .url("https://api.example.com/users")
    .cacheControl(cacheControl)
    .build()

Сравнение библиотек

БиблиотекаУровеньProsCons
HttpURLConnectionНизкийВстроенаМного кода
OkHttpСреднийМощнаяМало абстракции
RetrofitВысокийDeclarativeЗависит от OkHttp
KtorСреднийCoroutinesНовая

Лучшие практики

✅ Делай так:

  • Используй Retrofit для REST API
  • Используй Dispatchers.IO для сетевых операций
  • Обрабатывай все ошибки
  • Используй timeout'ы
  • Кешируй часто используемые данные

❌ Избегай:

  • Сетевых запросов на Main потоке
  • Игнорирования ошибок
  • Отсутствия timeout'ов
  • Неконтролируемого кеширования

Вывод

Основные способы работы с сетью:

  1. Retrofit - рекомендуется (REST API)
  2. OkHttp - если нужна гибкость
  3. HttpURLConnection - встроено
  4. Ktor - современный подход
  5. WebSocket - для real-time

Всегда используй корутины и обработку ошибок.