Android Kotlin Extensions to bardzo przydatny plugin, który uprzyjemnia pracę nad aplikacjami Androidowymi. Możemy z jego pomocą ułatwić sobie proces wiązania widoków z obiektami takimi jak Activities, czy też Fragments. Plugin umożliwia także automatyczną implementację interfejsu Parcelable dla wybranych obiektów. W artykule tym pokażę Wam jak można skorzystać z dobrodziejstw tego rozszerzenia, ale przede wszystkim wyjaśnię jak Kotlin Extensions działają pod spodem.

Stare na nowe

 

Android Kotlin Extensions tak naprawdę są już częścią standardowego pluginu Kotlina, jednak aby z nich skorzystać musimy jawnie określić taką chęć w pliku bulid.gradle (na poziomie modułu):

Teraz wystarczy pozwolić Gradle zbudować projekt i wszystko mamy gotowe.

Każdy, kto choćby przez krótką chwilę maiła styczność z procesem tworzenia aplikacji dla Androida, doskonale zna poniższy sposób przypisywania widoków layout’u do poszczególnych zmiennych:

Layout:

Obiekt typu Activity:

Można było oczywiście skorzystać z rozwiązań takich jak ButterKnife, ale nic nie oferowało takiego ułatwienia jak rozszerzenie przygotowane specjalnie dla Kotlina.

Powyższy przykład można teraz skrócić do tego:

Prawda, że wygodniej? Stosowny import zostanie dodany automatycznie. Dzięki niemu kompilator będzie wiedział, że chcemy skorzystać z odpowiedniego rozszerzenia. Wszystko bardzo fajnie wygląda, ale warto zastanowić się co tak naprawdę kryje się za tą sztuczką 😵.

 

Kotlin Extensions od kuchni

 

Z Kotlinem i Javą w Androidzie jest taki sam problem jaki powstał jakiś czas temu w przypadku Swift’a oraz Objective-C. Z jednej strony nowy język jest znacznie przyjemniejszy dla oka, z drugiej jednak ukrywa on wiele ze szczegółów implementacji. W przypadku programistów z kilkuletnim stażem na karku problem nie wydaje aż się tak istotny, ponieważ istnieje duże prawdopodobieństwo, że w trakcie swojej pracy z Javą i Androidem (lub Objective-C i iOS) przerobili wszystko od podstaw. Inaczej ma się jednak sprawa z osobami, które dopiero zaczynają swoją przygodę z daną platformą. Muszą one wykazać odrobinę dobrej woli, aby zgłębiać metody, które powoli odchodzą w zapomnienie.

Wróćmy na chwilę do poprzedniego przykładu. Android Studio posiada bardzo przydatną funkcję, która pozwala nam sprawdzić jak będzie się prezentował nasz kod po kompilacji do bytecode’u. Wystarczy wybrać Tools -> Kotlin -> Show Kotlin Bytecode. Tak będzie prezentował się nasz przykład po konwersji (wersja mocno skrócona):

 

Taki zapis jest oczywiście mało czytelny, ale za pomocą przycisku Decompile znajdującego się w górnej części okna, możemy skonwertować nasz kod do reprezentacji w Javie. Chwilę pewnie Wam zajmie przyzwyczajenie się do takiego zapisu, ale w końcu odnajdziecie znajome akcenty:

Dzięki takiemu zapisowi możemy sprawdzić jak Kotlin Extensions działają w praktyce.

Bardzo ciekawa rzecz znajduje się niemal na samej górze. Jest to prywatne pole _$_findViewCache, które wykorzystuje HashMap do budowania cache dla naszych widoków. Dzięki temu operacja wyszukania zostanie wykonana tylko raz. Każde kolejne wywołanie spowoduje „wyciągnięcie” widoku z przechowalni. Oczywiście w ramach danego cyklu życia obiektu.

Druga bardzo ciekawa rzecz znajduje się w funkcji _$_findCachedViewById():

Jak się okazuje Kotlin nie wykosztuje żadnych magicznych sztuczek. Wiązanie widoków z danym obiektem odbywa się w dalszym ciągu na tych samych zasadach. Kotlin jedynie sprytnie ukrywa przed nami ten fakt. Podczas kompilacji zostaną wykonane standardowe operacje niewidoczne na pierwszy rzut oka. Warto również zwrócić uwagę na funkcję _$_clearFindViewByIdCache(), za pomocą której można wyczyści cache dla danego widoku. Przydatne w przypadku fragmentów, o czym będzie za chwilę.

Przejdziemy sobie teraz przez kilka przykładów wykorzystania Kotlin Android Extensions sprawdzając jednocześnie jak w rzeczywistości wygląda implementacja danej funkcjonalności.

 

Wiązanie widoków z Fragmentami

 

W pierwszym przykładzie pokazałem Wam jak KAE współpracują z obiektami Activty. Możemy z skorzystać z nich jednak także w przypadku Fragmentów. Użyjemy tego samego layout’u jak w przypadku Aktywności:

Sprawdźmy jak będzie prezentował się kod po dekompilacji:

Różnicę możemy dostrzec na samym końcu. W chwili usunięcia widoku ze stack’u następuje automatyczne wyczyszczenie cache. Dzieje się tak dlatego, że w przypadku Fragmentów, widok może zostać w każdej chwili utworzony na nowo, natomiast sama instancja obiektu Fragment pozostanie nienaruszona. Widoki znajdujące się w cache będę już nieaktualne, więc najlepiej będzie utworzyć je na nowo.

 

Implementacja Parcelable

 

Od wersji 1.1.4 możemy również skorzystać z automatycznej implementacji Parcelable. Musimy jednak w bulid.gradle (ponownie na poziomie modułu) ustawić odpowiednią flagę, która da nam dostęp do funkcji traktowanych na tym etapie jako eksperymentalne:

Korzystając z instrukcji @Pracelize możemy z łatwością przystosować niemal każdy obiekt do korzystania z Parcelable:

Plugin wykona za nas całą żmudą pracę. Tak będzie prezentował się kod po dekompilacji:

Dodanie obiektu do Intenta jest równie banalne:

@Parcelize wymaga, aby wszystkie pola klasy przeznaczone do serializacji, zostały umieszczone w głównym konstruktorze. Nie będziemy mogli skorzystać także z @Parcelize, jeżeli przynajmniej jeden z argumentów konstruktora nie będzie polem klasy.

 

Edycja cache

 

Korzystając z instrukcji @ContainerOptions możemy określi w jaki sposób będzie budowane cache dla naszych widoków. Możemy również całkowicie zrezygnować z tej opcji. Domyślną implementacją dla cache jest HashMap, ale możemy również skorzystać ze SparseArray. Tak na tą chwilę prezentują się dostępne opcje:

A tak będzie wyglądała implementacja:

Natomiast kod po dekompilacji będzie wyglądał tak:

Podczas budowaniu cache, HashMap zostało zastąpione przez strukturę SparseArray, która choć wolniejsza, to będzie potrzebowała mniejszych zasobów pamięci.

 

Słowo na drogę

 

Podobnych rozwiązań do Android Kotlin Extensions jest jeszcze kilka, jak na przykład Anko. Każde z nich ukrywa przed nami pewien poziom złożoności.  Jak sami mogliście się przekonać, Kotlin Extensions swoje działanie opierają na prostych rozwiązaniach, które tylko z pozoru mogą wydawać się czymś skomplikowanym. Warto czasami prześwietlić dane narzędzie, choćby tylko z czystej ciekawości. Przy okazji nauczymy się czegoś nowego o platformie, na której pracujemy. Do następnego 🧐.

 

Link do grafiki tytułowej


 

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *