Kotlin'e Giriş: İnsanlar İçin Android Programlama

Yayınlanan: 2022-03-11

Mükemmel bir Android dünyasında Java'nın ana dili gerçekten modern, açık ve zariftir. Daha fazlasını yaparak daha az yazabilirsiniz ve ne zaman yeni bir özellik ortaya çıkarsa, geliştiriciler onu Gradle'daki sürümü artırarak kullanabilirler. Sonra çok güzel bir uygulama oluştururken, tamamen test edilebilir, genişletilebilir ve bakımı yapılabilir görünüyor. Faaliyetlerimiz çok büyük ve karmaşık değil, veri kaynaklarını veritabanından web'e tonlarca farklılık olmadan değiştirebiliriz vb. Kulağa harika geliyor, değil mi? Ne yazık ki, Android dünyası bu kadar ideal değil. Google hala mükemmellik için çabalıyor, ancak hepimiz biliyoruz ki ideal dünyalar yok. Bu nedenle, Android dünyasındaki bu büyük yolculukta kendimize yardım etmeliyiz.

Kotlin Nedir ve Neden Kullanmalısınız?

Yani birinci dil. Java'nın zarafet veya netlik ustası olmadığını düşünüyorum ve ne modern ne de etkileyici (ve sanırım aynı fikirdesiniz). Dezavantajı, Android N'nin altında hala Java 6 ile sınırlı olmamızdır (Java 7'nin bazı küçük parçaları dahil). Geliştiriciler, kodlarında lambda ifadelerini kullanmak için RetroLambda'yı da ekleyebilir; bu, RxJava kullanırken çok faydalıdır. Android N'nin üzerinde, Java 8'in bazı yeni işlevlerini kullanabiliriz, ancak yine de o kadar eski, ağır Java'dır. Android geliştiricilerinin "Keşke Android'in, iOS'un Swift ile yaptığı gibi daha güzel bir dili desteklemesini isterdim" dediğini çok sık duyuyorum. Peki ya size sıfır güvenlik, lambdalar ve diğer birçok yeni özellik ile çok güzel, basit bir dil kullanabileceğinizi söylesem? Kotlin'e hoş geldiniz.

Kotlin nedir?

Kotlin, JetBrains ekibi tarafından geliştirilen yeni bir dildir (bazen Android için Swift olarak da adlandırılır) ve şu anda 1.0.2 sürümündedir. Android geliştirmede kullanışlı kılan şey, JVM bayt kodunu derlemesi ve JavaScript'e de derlenebilmesidir. Java ile tamamen uyumludur ve Kotlin kodu basitçe Java koduna dönüştürülebilir ve bunun tersi de mümkündür (JetBrains'ten bir eklenti vardır). Bu, Kotlin'in Java ile yazılmış herhangi bir çerçeveyi, kütüphaneyi vb. kullanabileceği anlamına gelir. Android'de Gradle ile entegre olur. Mevcut bir Android uygulamanız varsa ve tüm uygulamayı yeniden yazmadan Kotlin'de yeni bir özellik uygulamak istiyorsanız, sadece Kotlin'de yazmaya başlayın ve işe yarayacaktır.

Ancak 'harika yeni özellikler' nelerdir? Birkaçını sıralayayım:

Opsiyonel ve Adlandırılmış Fonksiyon Parametreleri

 fun createDate(day: Int, month: Int, year: Int, hour: Int = 0, minute: Int = 0, second: Int = 0) { print("TEST", "$day-$month-$year $hour:$minute:$second") }

Method createDate'i Farklı Şekillerde Çağırabiliriz

 createDate(1,2,2016) prints: '1-2-2016 0:0:0' createDate(1,2,2016, 12) prints: '1-2-2016 12:0:0' createDate(1,2,2016, minute = 30) prints: '1-2-2016 0:30:0'

Sıfır Güvenlik

Bir değişken boş olabilirse, onları yapmaya zorlamadıkça kod derlenmeyecektir. Aşağıdaki kodda bir hata olacaktır - nullableVar null olabilir:

 var nullableVar: String? = “”; nullableVar.length;

Derlemek için null olup olmadığını kontrol etmeliyiz:

 if(nullableVar){ nullableVar.length }

Veya daha kısa:

 nullableVar?.length

Bu şekilde, nullableVar null ise hiçbir şey olmaz. Aksi takdirde, türden sonra bir soru işareti olmadan değişkeni null olamaz olarak işaretleyebiliriz:

 var nonNullableVar: String = “”; nonNullableVar.length;

Bu kod derlenir ve nonNullableVar'a null atamak istersek derleyici bir hata gösterir.

Ayrıca çok kullanışlı bir Elvis operatörü var:

 var stringLength = nullableVar?.length ?: 0

Ardından, nullableVar null olduğunda (yani nullableVar?.length null değerini döndürür), stringLength 0 değerine sahip olur.

Değişken ve Değişmez Değişkenler

Yukarıdaki örnekte, bir değişken tanımlarken var kullanıyorum. Bu değişkendir, istediğimiz zaman yeniden atayabiliriz. Bu değişkenin değişmez olmasını istiyorsak (çoğu durumda yapmalıyız), val (değer olarak, değişken değil) kullanırız:

 val immutable: Int = 1

Bundan sonra, derleyici immutable'a yeniden atamamıza izin vermeyecektir.

Lambdalar

Hepimiz lambdanın ne olduğunu biliyoruz, bu yüzden burada onu Kotlin'de nasıl kullanabileceğimizi göstereceğim:

 button.setOnClickListener({ view -> Log.d("Kotlin","Click")})

Veya işlev tek veya son argüman ise:

 button.setOnClickListener { Log.d("Kotlin","Click")}

Uzantılar

Uzantılar, son olduklarında veya kaynak kodlarına erişimimiz olmadığında bile mevcut sınıfları "genişletebileceğimiz" çok yararlı bir dil özelliğidir.

Örneğin, düzenleme metninden bir dize değeri almak için, her seferinde editText.text.toString() yazmak yerine işlevi yazabiliriz:

 fun EditText.textValue(): String{ return text.toString() }

Veya daha kısa:

 fun EditText.textValue() = text.toString()

Ve şimdi, her EditText örneğiyle:

 editText.textValue()

Veya aynısını döndüren bir özellik ekleyebiliriz:

 var EditText.textValue: String get() = text.toString() set(v) {setText(v)}

Operatör Aşırı Yüklemesi

Bazen nesneleri eklemek, çarpmak veya karşılaştırmak istiyorsak yararlıdır. Kotlin, ikili operatörlerin (artı, eksi, plusAssign, aralık vb.), dizi operatörlerinin ( get, set, get range, set range) ve eşittir ve tekli işlemlerin (+a, -a, vb.) aşırı yüklenmesine izin verir.

Veri Sınıfı

Java'da bir User sınıfını üç özellikle birlikte uygulamak için kaç satır koda ihtiyacınız var: copy, equals, hashCode ve toString? Kaotlin'de sadece bir satıra ihtiyacınız var:

 data class User(val name: String, val surname: String, val age: Int)

Bu veri sınıfı, equals(), hashCode() ve copy() yöntemlerini ve ayrıca Kullanıcıyı şu şekilde yazdıran toString() yöntemlerini sağlar:

 User(name=John, surname=Doe, age=23)

Veri sınıfları ayrıca Kotlin belgelerinde görebileceğiniz bazı başka kullanışlı işlevler ve özellikler de sağlar.

Anko Uzantıları

Butterknife veya Android uzantılarını kullanıyorsunuz, değil mi? Ya bu kitaplığı kullanmanız gerekmiyorsa ve XML'deki görünümleri bildirdikten sonra onu kimliğine göre koddan kullanın (C#'taki XAML ile olduğu gibi):

 <Button android: android:layout_width="match_parent" android:layout_height="wrap_content" />
 loginBtn.setOnClickListener{}

Kotlin'in çok kullanışlı Anko uzantıları var ve bununla, aktivitenize loginBtn'nin ne olduğunu söylemenize gerek yok, bunu sadece xml'yi "içe aktararak" biliyor:

 import kotlinx.android.synthetic.main.activity_main.*

Anko'da aktivitelere başlama, kadeh kaldırma gibi pek çok faydalı şey var. Anko'nun asıl amacı bu değildir - koddan kolayca mizanpajlar oluşturmak için tasarlanmıştır. Dolayısıyla, programlı bir düzen oluşturmanız gerekiyorsa, bu en iyi yoldur.

Bu, Kotlin'in sadece kısa bir görünümüdür. Antonio Leiva'nın blogunu ve kitabını okumanızı tavsiye ederim - Android Geliştiricileri için Kotlin ve tabii ki resmi Kotlin sitesi.

MVP Nedir ve Neden?

Güzel, güçlü ve anlaşılır bir dil yeterli değildir. İyi bir mimariye sahip olmayan her dilde karmaşık uygulamalar yazmak çok kolaydır. Android geliştiricileri (çoğunlukla yeni başlayanlar, aynı zamanda daha gelişmiş olanlar) genellikle etraflarındaki her şey için Activity sorumluluğu verir. Etkinlik (veya Parça veya diğer görünüm) verileri indirir, kaydetmeye gönderir, sunar, kullanıcı etkileşimlerine yanıt verir, verileri düzenler, tüm alt görünümleri yönetir. . . ve çoğu zaman çok daha fazlası. Aktiviteler veya Fragmanlar gibi kararsız nesneler için çok fazla (ekranı döndürmek yeterlidir ve Aktivite 'Hoşçakal….' der).

Çok iyi bir fikir, sorumlulukları görüşlerden ayırmak ve onları olabildiğince aptal hale getirmektir. Görünümler (Etkinlikler, Parçalar, özel görünümler veya ekranda veri sunan her şey) yalnızca alt görünümlerini yönetmekten sorumlu olmalıdır. Görünümler, modelle iletişim kuracak ve onlara ne yapmaları gerektiğini söyleyecek sunuculara sahip olmalıdır. Bu kısaca Model-View-Presenter modelidir (bana göre katmanlar arasındaki bağlantıları göstermek için Model-Presenter-View olarak adlandırılmalıdır).

MVC vs MVP

"Hey, böyle bir şey biliyorum ve buna MVC deniyor!" - düşünmedin mi? Hayır, MVP, MVC ile aynı şey değildir. MVC modelinde, görünümünüz modelle iletişim kurabilir. MVP'yi kullanırken, bu iki katman arasında herhangi bir iletişime izin vermezsiniz - View'in Model ile iletişim kurmasının tek yolu Presenter aracılığıyladır. View'in Model hakkında bildiği tek şey veri yapısı olabilir. Görünüm, örneğin Kullanıcı'nın nasıl görüntüleneceğini bilir, ancak ne zaman olduğunu bilmez. İşte basit bir örnek:

View, “Ben Aktiviteyim, iki EditText'im ve bir Düğmem var. Biri düğmeye bastığında, bunu sunucuma söylemeli ve EditTexts'in değerlerini ona iletmeliyim. Hepsi bu kadar, bir sonraki tıklamaya veya sunucu bana ne yapacağımı söyleyene kadar uyuyabilirim.”

Sunucu bir yerin bir Görünüm olduğunu bilir ve bu Görünümün hangi işlemleri gerçekleştirebileceğini bilir. Ayrıca iki string aldığında, bu iki stringden User oluşturup, kaydetmek için modele veri göndermesi gerektiğini ve eğer kaydetme başarılı ise, 'Başarı bilgisini göster' görünümüne söyleyeceğini de biliyor.

Model sadece verilerin nerede olduğunu, nerede saklanması gerektiğini ve veriler üzerinde hangi işlemlerin yapılması gerektiğini bilir.

MVP'de yazılan uygulamaların test edilmesi, bakımı ve yeniden kullanımı kolaydır. Saf bir sunucu, Android platformu hakkında hiçbir şey bilmemelidir. Saf Java (veya bizim durumumuzda Kotlin) sınıfı olmalıdır. Bu sayede sunucumuzu başka projelerde yeniden kullanabiliriz. Ayrıca, Model, View ve Presenter'ı ayrı ayrı test ederek birim testleri de kolayca yazabiliriz.

MVP modeli, kullanıcı arayüzünü ve iş mantığını gerçekten ayrı tutarak daha iyi, daha az karmaşık kod tabanı sağlar.

Küçük bir arasöz: MVP, uygulamaları daha da esnek ve güzel bir şekilde mimariye dönüştürmek için Bob Amca'nın Temiz Mimarisinin bir parçası olmalıdır. Bir dahaki sefere bunun hakkında yazmaya çalışacağım.

MVP ve Kotlin ile Örnek Uygulama

Bu kadar teori yeter, biraz kod görelim! Tamam, basit bir uygulama oluşturmaya çalışalım. Bu uygulamanın temel amacı kullanıcı oluşturmaktır. İlk ekranda iki EditText (Ad ve Soyad) ve bir Buton (Kaydet) olacaktır. Adı ve soyadını girip 'Kaydet'i tıkladıktan sonra, uygulama 'Kullanıcı kaydedildi'yi göstermeli ve kaydedilen ad ve soyadının gösterildiği sonraki ekrana gitmelidir. Ad veya soyadı boş olduğunda, uygulama kullanıcıyı kaydetmemeli ve neyin yanlış olduğunu belirten bir hata göstermelidir.

Android Studio projesini oluşturduktan sonra ilk iş Kotlin'i yapılandırmak. Kotlin eklentisini kurmalısınız ve yeniden başlattıktan sonra Araçlar > Kotlin'de 'Projede Kotlin'i Yapılandır' seçeneğine tıklayabilirsiniz. IDE, Gradle'a Kotlin bağımlılıkları ekleyecektir. Mevcut bir kodunuz varsa, (Ctrl+Shift+Alt+K veya Code > Java dosyasını Kotlin'e Dönüştür) ile kolayca Kotlin'e dönüştürebilirsiniz. Bir şeyler yanlışsa ve proje derlenmiyorsa veya Gradle Kotlin'i görmüyorsa, GitHub'da bulunan uygulamanın kodunu kontrol edebilirsiniz.

Kotlin, yalnızca Java çerçeveleri ve kitaplıklarıyla iyi bir şekilde birlikte çalışmakla kalmaz, aynı zamanda zaten aşina olduğunuz araçların çoğunu kullanmaya devam etmenize de olanak tanır.

Artık bir projemiz olduğuna göre, ilk görünümümüzü - CreateUserView - oluşturarak başlayalım. Bu görünüm daha önce bahsedilen işlevlere sahip olmalıdır, böylece bunun için bir arayüz yazabiliriz:

 interface CreateUserView : View { fun showEmptyNameError() /* show error when name is empty */ fun showEmptySurnameError() /* show error when surname is empty */ fun showUserSaved() /* show user saved info */ fun showUserDetails(user: User) /* show user details */ }

Gördüğünüz gibi, Kotlin, işlev bildirmede Java'ya benzer. Bunların hepsi hiçbir şey döndürmeyen fonksiyonlardır ve sonuncusunun bir parametresi vardır. Fark bu, parametre tipi isimden sonra gelir. Görünüm arayüzü Android'den değil - bu bizim basit, boş arayüzümüz:

 interface View

Basic Presenter'ın arayüzü, View türünde ve en azından onDestroy yönteminde (örneğin, bu özelliğin null olarak ayarlanacağı) bir özelliğe sahip olmalıdır:

 interface Presenter<T : View> { var view: T? fun onDestroy(){ view = null } }

Burada başka bir Kotlin özelliği görebilirsiniz - arayüzlerde özellikleri bildirebilir ve ayrıca orada yöntemler uygulayabilirsiniz.

CreateUserView'ımızın CreateUserPresenter ile iletişim kurması gerekiyor. Bu Sunucunun ihtiyaç duyduğu tek ek işlev, iki dize argümanıyla saveUser'dır:

 interface CreateUserPresenter<T : View>: Presenter<T> { fun saveUser(name: String, surname: String) }

Ayrıca Model tanımına da ihtiyacımız var - daha önceki veri sınıfından bahsediliyor:

 data class User(val name: String, val surname: String)

Tüm interfaceleri tanımladıktan sonra uygulamaya başlayabiliriz.

CreateUserPresenter, CreateUserPresenterImpl'de uygulanacaktır:

 class CreateUserPresenterImpl(override var view: CreateUserView?): CreateUserPresenter<CreateUserView> { override fun saveUser(name: String, surname: String) { } }

Sınıf tanımlı ilk satır:

 CreateUserPresenterImpl(override var view: CreateUserView?)

Bir yapıcıdır, arayüzde tanımlanan görünüm özelliğini atamak için kullanırız.

CreateUserView uygulamamız olan MainActivity, CreateUserPresenter için bir referansa ihtiyaç duyar:

 class MainActivity : AppCompatActivity(), CreateUserView { private val presenter: CreateUserPresenter<CreateUserView> by lazy { CreateUserPresenterImpl(this) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) saveUserBtn.setOnClickListener{ presenter.saveUser(userName.textValue(), userSurname.textValue()) /*use of textValue() extension, mentioned earlier */ } } override fun showEmptyNameError() { userName.error = getString(R.string.name_empty_error) /* it's equal to userName.setError() - Kotlin allows us to use property */ } override fun showEmptySurnameError() { userSurname.error = getString(R.string.surname_empty_error) } override fun showUserSaved() { toast(R.string.user_saved) /* anko extension - equal to Toast.makeText(this, R.string.user_saved, Toast.LENGTH_LONG) */ } override fun showUserDetails(user: User) { } override fun onDestroy() { presenter.onDestroy() } }

Dersin başında sunucumuzu tanımladık:

 private val presenter: CreateUserPresenter<CreateUserView> by lazy { CreateUserPresenterImpl(this) }

Değişmez (val) olarak tanımlanır ve ilk ihtiyaç duyulduğunda atanacak tembel temsilci tarafından oluşturulur. Üstelik null olmayacağından eminiz (tanımdan sonra soru işareti yok).

Kullanıcı Kaydet düğmesine tıkladığında Görünüm, bilgileri EditTexts değerleriyle Presenter'a gönderir. Bu olduğunda, Kullanıcı kaydedilmelidir, bu nedenle Presenter'da saveUser yöntemini (ve Model'in bazı işlevlerini) uygulamamız gerekir:

 override fun saveUser(name: String, surname: String) { val user = User(name, surname) when(UserValidator.validateUser(user)){ UserError.EMPTY_NAME -> view?.showEmptyNameError() UserError.EMPTY_SURNAME -> view?.showEmptySurnameError() UserError.NO_ERROR -> { UserStore.saveUser(user) view?.showUserSaved() view?.showUserDetails(user) } } }

Bir Kullanıcı oluşturulduğunda, geçerliliğini kontrol etmek için UserValidator'a gönderilir. Daha sonra validasyon sonucuna göre uygun metod çağrılır. When() {} yapısı Java'daki switch/case ile aynıdır. Ancak daha güçlüdür - Kotlin, 'durumda' yalnızca enum veya int'nin değil, aynı zamanda aralıkların, dizelerin veya nesne türlerinin kullanımına da izin verir. Tüm olasılıkları içermeli veya başka bir ifadeye sahip olmalıdır. Burada, tüm UserError değerlerini kapsar.

view?.showEmptyNameError() (görünümden sonra soru işaretiyle) kullanarak NullPointer'dan korunuruz. Görünüm onDestroy yönteminde boş bırakılabilir ve bu yapı ile hiçbir şey olmaz.

Bir Kullanıcı modelinde hata olmadığında, UserStore'a onu kaydetmesini söyler ve ardından View'a başarıyı göstermesi ve ayrıntıları göstermesi talimatını verir.

Daha önce de belirtildiği gibi, bazı model şeyler uygulamamız gerekiyor:

 enum class UserError { EMPTY_NAME, EMPTY_SURNAME, NO_ERROR } object UserStore { fun saveUser(user: User){ //Save user somewhere: Database, SharedPreferences, send to web... } } object UserValidator { fun validateUser(user: User): UserError { with(user){ if(name.isNullOrEmpty()) return UserError.EMPTY_NAME if(surname.isNullOrEmpty()) return UserError.EMPTY_SURNAME } return UserError.NO_ERROR } }

Buradaki en ilginç şey UserValidator. Nesne kelimesini kullanarak, iş parçacıkları, özel kurucular vb. hakkında endişe duymadan bir singleton sınıfı oluşturabiliriz.

Sonraki şey - validateUser(user) yönteminde with(user) {} ifadesi var. Bu blok içindeki kod, nesne bağlamında yürütülür, ad ve soyadı ile iletilir, Kullanıcı'nın özellikleridir.

Ayrıca küçük bir şey daha var. Enum'dan UserValidator'a kadar yukarıdaki tüm kodlar, tanım tek bir dosyaya yerleştirilir (User sınıfının tanımı da burada). Kotlin, sizi her bir genel sınıfı tek bir dosyada (veya tam olarak dosya olarak isim sınıfını) bulundurmaya zorlamaz. Bu nedenle, bazı kısa ilgili kod parçalarınız varsa (veri sınıfları, uzantılar, işlevler, sabitler - Kotlin, işlev veya sabit için sınıf gerektirmez), projedeki tüm dosyalara yaymak yerine tek bir dosyaya yerleştirebilirsiniz.

Bir kullanıcı kaydedildiğinde, uygulamamız bunu göstermelidir. Başka bir Görünüme ihtiyacımız var - herhangi bir Android görünümü, özel Görünüm, Parça veya Etkinlik olabilir. Aktivite'yi seçtim.

Şimdi UserDetailsView arayüzünü tanımlayalım. Kullanıcıyı gösterebilir, ancak kullanıcı olmadığında da bir hata göstermelidir:

 interface UserDetailsView { fun showUserDetails(user: User) fun showNoUserError() }

Ardından, UserDetailsPresenter. Bir kullanıcı özelliğine sahip olmalıdır:

 interface UserDetailsPresenter<T: View>: Presenter<T> { var user: User? }

Bu arayüz UserDetailsPresenterImpl'de uygulanacaktır. Kullanıcı özelliğini geçersiz kılmak zorundadır. Bu özellik her atandığında, kullanıcı görünümde yenilenmelidir. Bunun için bir özellik ayarlayıcı kullanabiliriz:

 class UserDetailsPresenterImpl(override var view: UserDetailsView?): UserDetailsPresenter<UserDetailsView> { override var user: User? = null set(value) { field = value if(field != null){ view?.showUserDetails(field!!) } else { view?.showNoUserError() } } }

UserDetailsView uygulaması, UserDetailsActivity, çok basittir. Daha önce olduğu gibi, tembel yükleme ile oluşturulmuş bir sunucu nesnemiz var. Görüntülenecek kullanıcı, niyet yoluyla iletilmelidir. Şimdilik bununla ilgili küçük bir sorun var ve onu birazdan çözeceğiz. Niyetten kullanıcımız olduğunda, Görünümün onu sunucularına ataması gerekir. Bundan sonra, kullanıcı ekranda yenilenir veya boşsa, hata görünür (ve etkinlik sona erer - ancak sunum yapan kişinin bundan haberi yoktur):

 class UserDetailsActivity: AppCompatActivity(), UserDetailsView { private val presenter: UserDetailsPresenter<UserDetailsView> by lazy { UserDetailsPresenterImpl(this) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_user_details) val user = intent.getParcelableExtra<User>(USER_KEY) presenter.user = user } override fun showUserDetails(user: User) { userFullName.text = "${user.name} ${user.surname}" } override fun showNoUserError() { toast(R.string.no_user_error) finish() } override fun onDestroy() { presenter.onDestroy() } }

Nesneleri amaçlar aracılığıyla iletmek, bu nesnenin Ayrıştırılabilir arabirimi uygulamasını gerektirir. Bu çok 'kirli' bir iş. Şahsen, tüm YARATICILAR, mülkler, kaydetme, geri yükleme vb. nedeniyle bunu yapmaktan nefret ediyorum. Neyse ki, Kotlin için Parcelable uygun bir eklenti var. Kurduktan sonra, sadece tek bir tıklama ile Parcelable üretebiliriz.

Yapılacak son şey, MainActivity'mizde showUserDetails(user: User) öğesini uygulamaktır:

 override fun showUserDetails(user: User) { startActivity<UserDetailsActivity>(USER_KEY to user) /* anko extension - starts UserDetailsActivity and pass user as USER_KEY in intent */ }

Ve hepsi bu.

Kotlin'de demo Android uygulaması

Bir Kullanıcıyı kaydeden (aslında kaydedilmez, ancak bu işlevi sunum yapan kişiye veya görünüme dokunmadan ekleyebiliriz) ve ekranda sunan basit bir uygulamamız var. Gelecekte, iki aktiviteden bir aktivitede iki parçaya veya iki özel görünüme geçmek gibi, kullanıcının ekranda sunulma şeklini değiştirmek istersek, değişiklikler sadece View sınıflarında olacaktır. İşlevselliği veya modelin yapısını değiştirmezsek tabii. View'in tam olarak ne olduğunu bilmeyen sunucu, herhangi bir değişikliğe ihtiyaç duymayacaktır.

Android uygulamalarınızda performans sorunları mı yaşıyorsunuz? Bu optimizasyon ipuçlarına ve tekniklerine göz atın.

Sıradaki ne?

Uygulamamızda, her etkinlik oluşturulduğunda Presenter oluşturulur. Bu yaklaşım veya Presenter'ın etkinlik örnekleri arasında devam etmesi gerekiyorsa bunun tam tersi, İnternet'te çok tartışılan bir konudur. Benim için uygulamaya, ihtiyaçlarına ve geliştiriciye bağlı. Bazen sunucuyu yok etmek daha iyidir, bazen değil. Birinde ısrar etmeye karar verirseniz, bunun için LoaderManager'ı kullanmak çok ilginç bir tekniktir.

Daha önce de belirtildiği gibi, MVP Bob Amca'nın Temiz mimarisinin bir parçası olmalıdır. Ayrıca, iyi geliştiriciler, sunum yapanların etkinliklere bağımlılıklarını enjekte etmek için Dagger'ı kullanmalıdır. Ayrıca gelecekte kodun korunmasına, test edilmesine ve yeniden kullanılmasına yardımcı olur. Şu anda Kotlin, Dagger ile (resmi sürümden önce o kadar kolay değildi) ve ayrıca diğer yararlı Android kitaplıklarıyla çok iyi çalışıyor.

Sarmak

Benim için Kotlin harika bir dil. Hala harika insanlar tarafından geliştirilmekteyken modern, net ve etkileyici. Ve herhangi bir yeni sürümü herhangi bir Android cihazında ve sürümünde kullanabiliriz. Java'da beni ne kızdırırsa, Kotlin onu geliştirir.

Tabii ki, dediğim gibi hiçbir şey ideal değildir. Kotlin'in bazı dezavantajları da var. En yeni gradle eklentisi sürümleri (esas olarak alfa veya betadan) bu dilde iyi çalışmıyor. Birçok kişi, derleme süresinin saf Java'dan biraz daha uzun olduğundan ve apk'lerin bazı ek MB'lere sahip olduğundan şikayet eder. Ancak Android Studio ve Gradle hala gelişiyor ve telefonlarda uygulamalar için giderek daha fazla alan var. Bu yüzden Kotlin'in her Android geliştiricisi için çok güzel bir dil olabileceğine inanıyorum. Sadece bir deneyin ve ne düşündüğünüzü aşağıdaki yorumlar bölümünde paylaşın.

Örnek uygulamanın kaynak kodu Github'da mevcuttur: github.com/tomaszczura/AndroidMVPKotlin