Пишем без Retrofit'а, Gson'a и Kotlin Coroutines Android приложение

Порой нам хочется написать код без лишних библиотек, чтобы более глубоко понять основные принципы или просто ради интереса.

В качестве примера я написал простое Android приложение, которое позволяет юзерам найти значение русского слова:

image-loader.svg

В данном примере GET запрос реализован через встроенные средства Java, которые находятся в пакете java.net.*

Парсинг JSON осуществляется через встроенный в Android пакет org.json.*

А для выполнения запроса на background потоке я использую функции обратного вызова и Java пакет java.util.concurrent.*

Также для поиска реализован Debounce эффект с задержкой в 500 мс.

Ну что ж пройдемся по всем частям более подробно

Делаем GET запрос без Retrofit’а)

Покажу сразу код:

open class GetRequest(private val url: String) {

    private val executor = Executors.newSingleThreadExecutor()
    private val handler = Handler(Looper.getMainLooper())

    fun execute(onSuccess: (json: String) -> Unit, onError: (error: GetError) -> Unit) {
        executor.execute {
            try {
                val connection = URL(url).openConnection() as HttpsURLConnection
                connection.requestMethod = "GET"
                connection.setRequestProperty("Content-Type", "application/json; utf-8")
                connection.connectTimeout = 5000
                connection.readTimeout = 5000

                val reader = BufferedReader(InputStreamReader(connection.inputStream))
                val content = StringBuffer()
                var inputLine = reader.readLine()
                while (inputLine != null) {
                    content.append(inputLine)
                    inputLine = reader.readLine()
                }

                connection.disconnect()

                handler.post { onSuccess(content.toString()) }

            } catch (error: Exception) {
                handler.post {
                    if (error is UnknownHostException) {
                        onError(GetError.MISSING_INTERNET)
                    } else {
                        onError(GetError.OTHER)
                    }
                }
            }
        }
    }

}

Мы используем статический метод Executors.newSingleThreadExecutor() для создания одиночного пула потоков, который мы юзаем, чтобы выполнить наш запрос в background потоке.

Handler используется для возвращения результата на UI поток

HttpsURLConnection входит во встроенный пакет java.net.* и предназначен для выполнения сетевых запросов.

Параметры HttpsURLConnection я думаю вам понятны.

Затем мы читаем все данные через BufferedReader и отправляем результат дальше через функции обратного вызова, которые передаются в метод execute().

Обратите внимание, наш класс может иметь наследников.

В моем тестовом приложении это DictGetRequest:

class DictGetRequest(word: String) : 
	GetRequest("https://api.dictionaryapi.dev/api/v2/entries/ru/$word")

Страшный парсинг JSON’а вручную

© Habrahabr.ru