
Bu basit Android Uygulamasını oluşturdum (yazılı Kotlin ve Jetpack Compose) farklı HTTP İstemci kitaplıkları kullanarak REST API web hizmetine bağlanmanın farklı yollarını anlamama yardımcı olur.
Ben de bu kütüphaneleri kullanmanın hafızasını ve performansını ölçmeye çalıştım.
Bu REST API’sidir – Yemek Kategorileri TheMealDB’den uygulama almaya çalışır. JSON formatında döner.
Uygulama ile uygulanır OGVMancak aşağıdakiler yalnızca bu HTTP istemci kitaplıklarını oluşturmak için yapmanız gereken adımları vurgulamaktadır.
Ayrıntıları öğrenmek istiyorsanız, lütfen bu makalenin sonunda verilen kaynak koduna bakın.
1. Güçlendirme + Moshi
Bunu oluştururken öğrendiğim ilk yöntem bu Asteroid Rader Uygulaması Android Kotlin Developer Nanodegree Projelerimden birinde.
- Retrofit, REST API web hizmetine bağlanmak için HTTP istemci kitaplığıdır
- Moshi, JSON yanıtını Kotlin veri nesnesine ayrıştıran kitaplıktır.
Güçlendirme + Moshi Dönüştürücü Kitaplıklarını İçe Aktar
def retrofit_version = "2.9.0"
implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
implementation "com.squareup.retrofit2:converter-moshi:$retrofit_version"
def moshi_version = "1.12.0"
implementation "com.squareup.moshi:moshi:$moshi_version"
implementation "com.squareup.moshi:moshi-kotlin:$moshi_version"
Moshi için Veri Sınıfı Oluşturun
data class MoshiMealCategoriesResponse (
val categories: List<MoshiMealCategory>
)
data class MoshiMealCategory(
@Json(name="idCategory") val idCategory: String,
val strCategory: String,
val strCategoryDescription: String,
val strCategoryThumb: String
)
@Json
Moshi ek açıklamasıdır ve yalnızca val adınız JSON dizesinden farklıysa gereklidir.
Güçlendirme + Moshi API Arayüzünü Tanımlayın
interface RetrofitMoshiMealsApi {
@GET("categories.php")
suspend fun getMealCategories(): MoshiMealCategoriesResponse
}
Güçlendirme + Moshi API’si oluşturun
class RetrofitMoshiMealsWebService {
private val api: RetrofitMoshiMealsApi by lazy {
createMealsApi()
}
suspend fun getMealCategories(): MoshiMealCategoriesResponse {
return api.getMealCategories()
}
private fun createMealsApi(): RetrofitMoshiMealsApi {
val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
val retrofit = Retrofit.Builder()
.baseUrl(MainRepository.BASE_URL)
.addConverterFactory(MoshiConverterFactory.create(moshi))
.build()
return retrofit.create(RetrofitMoshiMealsApi::class.java)
}
}
2. Güçlendirme + Gson
Moshi’ye benzer şekilde Gson, JSON’u Kotlin veri nesnelerine seri hale getirmek ve seri durumdan çıkarmak için açık kaynaklı bir Java kitaplığıdır.
Moshi ithali yukarıda zaten gösterildiğinden, burada tekrar göstermeyeceğim.
Gson Dönüştürücü Kitaplığını İçe Aktar
implementation "com.squareup.retrofit2:converter-gson:$retrofit_version"
Gson için Veri Sınıfı Oluşturun
data class GsonMealCategoriesResponse (
val categories: List<GsonMealCategory>
)
data class GsonMealCategory(
@SerializedName("idCategory") val idCategory: String,
val strCategory: String,
val strCategoryDescription: String,
val strCategoryThumb: String
)
@SerializedName
şuna benzer Gson ek açıklamasıdır @Json
JSON dizginiz val adından farklıysa, Moshi ek açıklamasında.
Teknik olarak, tüm bu farklı JSON ayrıştırıcı uygulamaları için aynı veri sınıfını paylaşabilirim, ancak farklı ayrıştırıcı kitaplıkları için farklı açıklamalar gerektirdiğinden ayırmanın daha temiz olduğunu düşünüyorum.
Güçlendirme + Gson API Arayüzünü Tanımlayın
interface RetrofitGsonMealsApi {
@GET("categories.php")
suspend fun getMealCategories(): GsonMealCategoriesResponse
}
Güçlendirme + Gson API’si oluşturun
class RetrofitGsonMealsWebService {
private val api: RetrofitGsonMealsApi by lazy {
createMealsApi()
}
suspend fun getMealCategories(): GsonMealCategoriesResponse {
return api.getMealCategories()
}
private fun createMealsApi(): RetrofitGsonMealsApi {
val gsonConverterFactory = GsonConverterFactory.create()
val retrofit = Retrofit.Builder()
.baseUrl(MainRepository.BASE_URL)
.addConverterFactory(gsonConverterFactory)
.build()
return retrofit.create(RetrofitGsonMealsApi::class.java)
}
}
3. Güçlendirme + Kotlin Serileştirme
Moshi ve Gson’a benzer şekilde, Kotlin Serileştirme, JSON’u Kotlin veri nesnelerine seri hale getirmek ve seri durumdan çıkarmak için kullanılabilen resmi bir Kotlin kitaplığıdır.
aldığım tavsiyelerden biri Android Kotlin Geliştirici NonoDegree Kotlin Serileştirme kullanmaktır. Yansıma kullanmadığı için bellek ve performans daha iyidir.
Kotlin Serileştirme Eklentisi Ekle
Bunu ekle appbuild.gradle
plugins {
...
import project. id 'org.jetbrains.kotlin.plugin.serialization' version "$kotlin_version"
}
güncellediğinizden emin olun. build.gradle
de uygulama seviyede değil, proje seviye. Aşağıda bu uyarıyı görüyorsanız, yanlış bir şekilde güncellemiş olabilirsiniz. build.gradle
dosya (yani proje düzeyi).
Warning:(5, 1) kotlinx.serialization compiler plugin is not applied to the module, so this annotation would not be processed. Make sure that you've setup your buildscript correctly and re-import project.
Yanlış güncellediğimi anlamam biraz zaman aldı build.gradle
. İyi derlendi ancak çalışma zamanında başarısız oldu. Benim yaptığım hatayı yapma.
Kotlin Serileştirme Kitaplığını İçe Aktar
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2"
Kotlin Serileştirme Dönüştürücüsünü İçe Aktar + okhttp3 Kitaplıkları
Squareup’tan Retrofit için resmi bir Kotlin Serileştirme Dönüştürücüsü yok ve biz Jake Wharton’dan olanı kullanıyoruz.
implementation "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.8.0"
implementation "com.squareup.okhttp3:okhttp:4.9.3"
okhttp3
için gereklidir "application/json".toMediaType()
kullanım (aşağıya bakınız)
Kotlin Serileştirme için Veri Sınıfı Oluşturun
@Serializable
data class KotlinSerdesMealCategoriesResponse (
val categories: List<KotlinSerdesMealCategory>
)
@Serializable
data class KotlinSerdesMealCategory(
@SerialName("idCategory")
val idCategory: String,
val strCategory: String,
val strCategoryDescription: String,
val strCategoryThumb: String
)
Benzer @Json
(Moshi) ve @SerializedName
(Gson), @SerialName
Kotlin Serileştirme için kullanılır. Lütfen sınıfa açıklama eklemeniz gerektiğini unutmayın. @Serializable
Kotlin Serileştirmeyi kullanmak için.
Güçlendirme + Kotlin Serileştirme API Arayüzünü Tanımlayın
interface RetrofitKotlinSerdesMealsApi {
@GET("categories.php")
suspend fun getMealCategories(): KotlinSerdesMealCategoriesResponse
}
Güçlendirme Yapın + Kotlin Serileştirme
class RetrofitKotlinSerdesMealsWebService {
private val api: RetrofitKotlinSerdesMealsApi by lazy {
createMealsApi()
}
suspend fun getMealCategories(): KotlinSerdesMealCategoriesResponse {
return api.getMealCategories()
}
@OptIn(ExperimentalSerializationApi::class)
private fun createMealsApi(): RetrofitKotlinSerdesMealsApi {
val contentType = "application/json".toMediaType()
val retrofit = Retrofit.Builder()
.baseUrl(MainRepository.BASE_URL)
.addConverterFactory(Json.asConverterFactory(contentType))
.build()
return retrofit.create(RetrofitKotlinSerdesMealsApi::class.java)
}
}
Lütfen eklemeniz gerektiğini unutmayın @OptIn(ExperimentalSerializationApi::class)
dönüştürücü kitaplığını kullanmak için. Ayrıca isteğe bağlı derleyici argümanını da eklemeniz gerekir. build.gradle
modül seviyesi dosyası.
android {
...
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
kotlinOptions {
freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
}
}
}
4. Ktor İstemcisi + Kotlin Serileştirme
Ktor istemcisi, çok platformlu bir HTTP istemci kitaplığıdır.
Kotlin Serileştirme Kitaplıkları ile Ktor İstemcisini İçe Aktarın
def ktor_version = "1.6.8"
implementation "io.ktor:ktor-client-core:$ktor_version"
implementation "io.ktor:ktor-client-cio:$ktor_version"
implementation "io.ktor:ktor-client-serialization:$ktor_version"
Ktor İstemcisi Oluşturun ve API Arayüzünü Uygulayın
Veri sınıfı, yukarıdaki Kotlin Serileştirme veri sınıfı ile tamamen aynıdır. Bu yüzden burada tekrar göstermeyeceğim.
Ktor Client’ı kullanmak için, Moshi’nin gerektirdiği şekilde arayüzü tanımlamamıza gerçekten gerek yok. sadece arayabilirsin ktorHttpClient.get("URL here")
API doğrudan.
class KtorKotlinSerdesMealsWebService {
private val ktorHttpClient = HttpClient {
install(JsonFeature) {
serializer = KotlinxSerializer()
}
}
suspend fun getMealCategories(): KotlinSerdesMealCategoriesResponse {
return ktorHttpClient.get("${MainRepository.BASE_URL}categories.php")
}
}
Bellek ve Performans
bunu ekledim Enable Performance Test
ana ekrana onay kutusu. İşaretlendiğinde, performans testi için API’yi 10 kez arayacaktır.
Bazı hafıza ve performans testleri yaptım ve işte sonuçlar. Birkaç kez koştum ve ortalamayı aldım. Ayrıca, sonuçların çakışmaması için HTTLP istemci kitaplığını bağımsız olarak çalıştırmak için uygulamayı yeniden başlattım.
HTTP İstemci Kitaplığı | Hafıza kullanımı | Verim |
Güçlendirme + Moshi | 22 M bayt | 4.8 saniye |
Güçlendirme + Gson | 19 M bayt | 4.9 saniye |
Güçlendirme + Kotlin Serileştirme | 20 M bayt | 4.9 saniye |
Ktor İstemcisi + Kotlin Serileştirme | 22 M bayt | 10.8 saniye |
için bellek ve performans Güçlendirme + Gson ve Güçlendirme + Kotlin Serileştirme benzerdir. Yenileme + Moshi benzer performansla biraz daha fazla bellek kullanır, ancak yalnızca yanlış pozitif olabilir.
Ama, ne olur Ktor Cilent? Ktor Client’ın performansı yaklaşık 2 kat daha yavaş!
Çözüm
Hafızayı ve performansı çalıştırmadan önce bir izlenimim vardı. Ktor İstemcisi + Kotlin Serileştirme en iyi seçenek olmalı, ama en kötüsü olduğu ortaya çıktı! Belki de çok platformlu ek yük nedeniyledir?
Ayrıca, Kotlin Serileştirmenin daha az bellek kullandığı ve daha hızlı olduğu iddiası muhtemelen doğru değildir. Moshi ve Gson ile aşağı yukarı aynı mı yoksa testi ben yapmadım değil mi?
çok açık seçim Retrofit.
Şahsen, muhtemelen seçeceğim
- Moshi, Gson üzerinden çünkü Moshi, Gson’dan daha yeni bir kitaplık
- Retrofit Kotlin Serileştirme Dönüştürücüsü resmi bir kitaplık DEĞİLDİR (kare kitaplıkların bir parçası değildir).
Yaptığım bu küçük araştırma göz önüne alındığında, hedefim Güçlendirme + Moshi.
Kaynak kodu
GitHub Deposu: Demo_SimpleRestAPI