Java 17+ czy Kotlin wraz z Jetpack Compose?

0

Pytanie o wybór technologii. Mam stworzyć natywną aplikację mobilną (odpowiednik aplikacji webowej), która będzie działać szybko i zajmować mało miejsca. Kiedyś zacząłem uczyć się Androida i przerwałem, a teraz wchodzę w ten sam kurs i jest już Jetpack Compose ściśle powiązany z Kotlinem.

https://developer.android.com/training/basics/firstapp

Ostatnio Google ostro promuje Compose.

Nie chcę spędzić długich godzin na nauce i rozwiązywaniu problemów, bo opóźnienie w projekcie mamy już duże.

Mam dylemat, czy iść z duchem czasu i uczyć się Kotlina + Compose, czy pozostać przy Javie i tworzyć UI w tradycyjny sposób. Mam jedynie doświadczenie w języku Java i jakiś czas temu przechodziłem "Build your first app" jeszcze w tradycyjny sposób, gdzie UI to były zasoby w XML-u.

Nasuwają się wątpliwości:

  • Czy aplikacje w Compose działają szybko na starszych telefonach?
  • Czy narzut w Compose jest duży, tzn. czy takie aplikacje zajmują dużo miejsca?
  • Czy Google niedługo przestanie wspierać Javę i przejdzie całkowicie na Kotlina?
  • Gdzie jest większy wybór komponentów i większe wsparcie społeczności?
  • Co może mnie bardziej ograniczać i powodować więcej problemów?

Kiedyś skompilowałem Hello World w Kotlinie i apka ważyła 50 MB, ale podobno to nie wina Kotlina, tylko bibliotek, które standardowo są dołączane.

3
Shiba Inu napisał(a):
  • Czy Google niedługo przestanie wspierać Javę i przejdzie całkowicie na Kotlina?

Jako że na androdzie nie znam się w ogóle, ale na Kotlinie już trochę tak i minimalnie na Javie to mogę powiedzieć że przez Javę Google miało już dużo problemów prawnych z Oracle i pewnie to jest głównym powodem że Kotlinie jest tak promowany na androida

Czy aplikacje w Compose działają szybko na starszych telefonach?

Nie wiem ale jestem ciekawe czy Java 17+ zadziała na starszych telefonach? Kotlin kompiluje się do bytecodu JDK 8. Java 17 kompiluje się do JDK 17 co może być problematyczne. Nie wiem niestety jak to wygląda dla Androida

Kiedyś skompilowałem Hello World w Kotlinie i apka ważyła 50 MB, ale podobno to nie wina Kotlina, tylko bibliotek, które standardowo są dołączane.

A ile dla porównania miał Hello World w Javie? Bo to decydująca informacja przy takim porównywaniu Hello Worldów :P

5

Skąd ci się wzięło, że użyjesz Javy 17? Użyjesz tylko Javy 8 i kilku rzeczy z 9:
https://developer.android.com/studio/write/java8-support#library-desugaring

A co do odpowiedzi na pytanie to Kotlin i JetpackCompose. W ostateczności Kotlin i stare api Androida, ale ja bym polecał raczej JetpackCompose. Pisanie w Javie nie ma żadnego uzasadnienia.

2

Podobnie jak @gajusz800 nie widzę najmniejszego powodu, do używania obecnie Javy w Androidzie. Nie jestem w stanie powiedzieć, czy Compose, czy "stare API", bo moja przygoda z aplikacjami mobilnymi skończyła się lata temu. Nie sądzę, żeby w przypadku aplikacji, która ma być mobilną wersją strony www miało to znaczące przełożenie na czas developmentu. Gdybym był na twoim miejscu, pewnie wybrałbym Compose, ale to raczej pójście w nowe rozwiązania, niż jakaś głęboko uzasadniona decyzja.

@KamilAdam: Na Androidzie, Java nie kompiluje się do bytecode Javy. Tzn. kompiluje się, ale tylko na trochę.https://pl.wikipedia.org/wiki/Android_Runtime

2

No podstawowa różnica jest taka, że JetpackCompose podobnie jak Flutter to podejście deklaratywne, a tzw stare api imperatywne. Ja wolę to pierwsze i raczej to jest obecnie przyszłość. Poza tym JetpackCompose jest nowsze, od początku powstało z myślą o Kotlinie i nie ma tych naleciałości, które utrudniały wszytko, bo ktoś tym razem to lepiej przemyślał.

https://developer.android.com/jetpack/compose/mental-model

Ja akurat obecnie używam głównie Fluttera, ale starego Android SDK już bym nie chciał nawet kijem dotknąć, jeśli już natywny Android to JetpackCompose.

0
KamilAdam napisał(a):

A ile dla porównania miał Hello World w Javie? Bo to decydująca informacja przy takim porównywaniu Hello Worldów :P

Z tego, co pamiętam, to w Javie tylko kilka MB, a w Kotlinie ok. 50 MB. Mogę to jeszcze sprawdzić teraz.

gajusz800 napisał(a):

Skąd ci się wzięło, że użyjesz Javy 17? Użyjesz tylko Javy 8 i kilku rzeczy z 9:

No szkoda. Kod w Javie 11 też nie chciał się kompilować.

gajusz800 napisał(a):

A co do odpowiedzi na pytanie to Kotlin i JetpackCompose. W ostateczności Kotlin i stare api Androida, ale ja bym polecał raczej JetpackCompose. Pisanie w Javie nie ma żadnego uzasadnienia.

A jak obecnie wygląda rynek? Jestem programistą Java i w zasadzie powinienem pisać w Javie (tutaj jestem ograniczony do wersji 8), ale też nie chcę robić czegoś, co za chwilę trzeba będzie przepisywać. Może warto się zastanowić, jakie są zalety pozostania przy Javie, może biblioteki, wykorzystanie istniejącego kodu? Z testów wynika, że nie ma dużej różnicy w szybkości działania, bo wszystko i tak kompiluje się do tego samego kodu bajtowego.

Druga kwestia, czy używać Jetpack Compose. Ile czasu zajmie nauka? Czy są komponenty, czy dopiero to raczkuje? Na razie potrzebuję ekranu logowania, formularzy, pewnie menu dolnego lub górnego podobnego jak w Material UI. Dla starego UI w IntelliJ (Android Studio) są szablony takich Activity. No i w Compose chyba wszystko trzeba zmieniać z poziomu kodu, a nie przeciągnij i upuść + edycja własności z GUI. Analogia trochę jak Swing a JavaFX.

Załóżmy, że mam tydzień na naukę i zależy mi na tym, żeby szybko wejść na dobre tory.

Edit: wiem, że Flutter teraz na topie, ale trzeba by przekonać klienta i uczyć się jeszcze Darta :)

No podstawowa różnica jest taka, że JetpackCompose podobnie jak Flutter to podejście deklaratywne, a tzw stare api imperatywne. Ja wolę to pierwsze i raczej to jest obecnie przyszłość.

gajusz800 napisał(a):

No podstawowa różnica jest taka, że JetpackCompose podobnie jak Flutter to podejście deklaratywne, a tzw stare api imperatywne. Ja wolę to pierwsze i raczej to jest obecnie przyszłość. Poza tym JetpackCompose jest nowsze, od początku powstało z myślą o Kotlinie i nie ma tych naleciałości, które utrudniały wszytko, bo ktoś tym razem to lepiej przemyślał.

Ale czy deklaratywne budowanie interfejsu było takie złe? Widać odejście od WYSIWYG, gdzie projektujesz i widzisz od razu efekt.

1

Ale czy deklaratywne budowanie interfejsu było takie złe? Widać odejście od WYSIWYG, gdzie projektujesz i widzisz od razu efekt.

Chyba miałeś na myśli imperatywne. No co kto woli. We Flutterze (pewnie w JetpackCompose też) też widzisz od razu efekt, na uruchomionej aplikacji tzn jak coś zmienisz to zmiany są od razu widoczne bez konieczności ponownej kompilacji.

Nie wiem czy jest dużo pracy w JetpackCompose, jak ja dziś pewnie nie, dopiero niedawno wyszła wersja stabilna. Ale jeśli mówimy o pracy, to tylko Kotlin, Java ci się tu nie przyda.

4
Shiba Inu napisał(a):

A jak obecnie wygląda rynek? Jestem programistą Java i w zasadzie powinienem pisać w Javie (tutaj jestem ograniczony do wersji 8), ale też nie chcę robić czegoś, co za chwilę trzeba będzie przepisywać. Może warto się zastanowić, jakie są zalety pozostania przy Javie, może biblioteki, wykorzystanie istniejącego kodu? Z testów wynika, że nie ma dużej różnicy w szybkości działania, bo wszystko i tak kompiluje się do tego samego kodu bajtowego.

Dowcip polega na tym, że znając Javę, jesteś w stanie bardzo płynnie przejść do programowania w Kotlinie:

  1. Przeklikujesz sobie Kotlinową piaskownicę

  2. Zaczynasz pisać jak w Java, tylko w Kotlinie. Bez wnikania w code suggars, które Kotlin oferuje. Prawie każdy kawałek kodu z Javie da się 1:1 przetłumaczyć na Kotlina. Jedynym problemem mogą być typy generyczne, bo one faktycznie się czasami nie mapują na Javę.

  3. Przeklinasz ile wlezie null safety, kolekcje niemutowalne....

  4. Już normalnie pracując, doczytujesz jakieś językowe smaczki, zaczynasz stosować, lubić prostotę składni, zaczynasz coraz więcej kodu pisać w funkcjach (bo po co w klasach..).

  5. Kończy ci się projekt i wracasz do Java i klniesz na czym świat stoi, bo wiesz, że można łatwiej, przyjemniej, czytelniej, ale nawet wtedy jesteś lepszym programistą Java, bo w punkcie 3 nauczyłeś się, że zmienna ma być final i nie null, kolekcja powinna być niemutowalna i o to dbasz.

Ta ścieżka wyżej, to moja historia i kilku innych osób. 1 dzień nauki wystarczy, żeby zacząć pracę w tym języku (jeżeli znasz już Java)

Możesz w Kotlinie używać praktycznie każdej biblioteki, jakiej używałeś w Javie (ok, Lomboka nie próbowałem), możesz napisać w kotlinie Springowy backend (ale po co...). Jeżeli napiszesz bibliotekę w Kotlinie, to możesz jej używać w Javie (i nikt się nie zorientuje), możesz w Kotlinie używać standardowej biblioteki Java... itd. Potencjalne problemy są na poziomie narzędzi, bo ktoś nie zainstalował pluginu do Kotlina w Sonarqube, nie użyjesz go jako lambdy w chmurze itd.

Rynek wygląda tak, że pod Androida już praktycznie nie pisze się w Javie. Poza Androidem bardzo mało pisze się w Kotlinie, ale trend jest rosnący. W moim projekcie właściwie wszystkie nowe komponenty backendowe startują w tej chwili w Kotlinie.

0

Czy ten compose ma szanse dzialac na IOS? Sa jakies prace nad tym prowadzone? Tez musze napisac appke, ale na razie flutter wygrywa ze wzgledu na multiplatformowosc.

0
Jan Ko napisał(a):

Czy ten compose ma szanse dzialac na IOS? Sa jakies prace nad tym prowadzone?

Nie. Zresztą po co, skoro jest Flutter i jest bardzo podobny?

0

Czyli całkowicie odchodzimy od idei graficznego projektowania interfejsu przez dewelopera? Pamiętam projekt na studia, gdzie cały interfejs w GTK musiałem pisać z palca, bo nie istniał RAD dla tej biblioteki. O ile szybciej by było poustawiać kontrolki i ich własności w GUI. Obecnie istnieje Glade.

W Compose przyjęto założenie, że projektantka stworzy interfejs w Figmie, a deweloper podepnie gotowe komponenty.

https://developer.android.com/jetpack/compose/tooling/relay

W Compose musisz już wiedzieć, jakie są komponenty, jakie własności (lub co chwilę zaglądać do dokumentacji), bo GUI nie zawsze podpowiada wszystkie dostępne opcje. Dużo rzeczy piszesz z palca, które byś normalnie ustawił z poziomu Designera. Na razie przechodzę tutorial Compose, ale aplikację muszę szybko zacząć, więc mam dylemat, czy na siłę iść w Compose, czy jednak wykonać ją tradycyjnym sposobem, gdzie jest wiele szablonów i jest integracja z Material.

Niestety muszę przebudować projekt, by widzieć zmiany w Compose. Może czegoś nie ustawiłem.

Piszę jednak w Kotlinie.

0
Shiba Inu napisał(a):

Niestety muszę przebudować projekt, by widzieć zmiany w Compose. Może czegoś nie ustawiłem.

A masz najnowsze Android Studio? Wygląda na to że dopiero niedawno to weszło do wersji stable:

Compose Preview updates automatically - In earlier versions of Android Studio, you had to manually refresh Compose Previews after making changes. In Electric Eel, Previews update automatically after you make compatible code changes in the same file, allowing you to iterate on your UI faster. If your code change was incompatible, Previews will show a “Needs Rebuild”

https://android-developers.googleblog.com/2023/01/android-studio-electric-eel.html

1

Używam IntelliJ IDEA Ultimate, który ma wbudowaną wtyczkę do Androida.

Na razie przechodzę przewodniki Compose. Warto też przeczytać wprowadzenie:

https://developer.android.com/jetpack/compose/mental-model

2

Nie mam dużego doświadczenia, napisałem w życiu kilka niewielkich aplikacji na Androida. Jedną w okolicach 2010 roku, drugą w okolicach 2015, trzecią zacząłem w 2022 roku.

Z moich obserwacji wynika, że:

  1. W Kotlinie pisze się znacznie przyjemniej i szybciej. Nigdy więcej nie wrócę do Javy na Androidzie.
  2. W Kotlinie jest duży nacisk na "nowe podejście" do nullability. Powoduje to trochę problemów i masę warningów kiedy się konwertuje jakiś stary kod w Javie na Kotlin, używa w projekcie plików Java (bez konwersji), albo chce się pisać "po staremu", czyli deklarujemy a później wypełniamy pola albo i nie. Trzeba się nauczyć pisać kod w którym nullable jest tylko to, co powinno być nullable. Jak ktoś miał do czynienia z programowaniem funkcyjnym, rozumie na czym ono polega to jest dość łatwo.
  3. Miałem jeden poważny problem po przejściu na Kotlin - skrypty Gradle mają inną składnię, trzeba poświęcić trochę czasu żeby to opanować, a później może (ale nie musi) okazać się, że nie wszystko co się dało w Gradle pod Javę da się zrobić w Gradle pod Kotlin. Ja miałem taki problem z Gradle SSH Plugin.
  4. Filozofia tworzenia UI w Androidzie ciągle jest niedopracowana się zmienia, pełno jest nieprzemyślanych rozwiązań, dokumentacja nie nadąża, na developer.android.com pełno jest nieaktualnych i/lub złych (powodujących duże problemy z późniejszym rozwojem albo utrzymaniem projektu).
  5. "Reklamowane" biblioteki, które miały ułatwić życie programistom często je komplikują. Na przykład próbowałem używać DataBinding, ale z czasem okazało się, że to jest gorsze niż klepanie findViewById. Aktualnie używam "odchudzonej wersji", czyli ViewBinding. Jest też to nowe API do nawigacji. Fajnie to wygląda na papierze, ale jak się zacznie z tym pracować dłużej to zaczyna być denerwujące i tworzy nowe problemy w projekcie, bo nie działa z tym czy tamtym.
0
Kamil A napisał(a):

W Kotlinie jest duży nacisk na "nowe podejście" do nullability. Powoduje to trochę problemów i masę warningów kiedy się konwertuje jakiś stary kod w Javie na Kotlin, używa w projekcie plików Java (bez konwersji), albo chce się pisać "po staremu", czyli deklarujemy a później wypełniamy pola albo i nie. Trzeba się nauczyć pisać kod w którym nullable jest tylko to, co powinno być nullable. Jak ktoś miał do czynienia z programowaniem funkcyjnym, rozumie na czym ono polega to jest dość łatwo.

To się nazywa null safety i jako koncepcja to nie nowość, C# ma to od dawna. Z tą różnicą, że w C# to nie jest prawdziwe null safety, bo typy nullable to jest Nullable<T> a zapis np int? to tylko lukier składniowy.

W Kotlinie i Dart int i int? to są inne typy i jak coś nie jest nullable to musi dostać wartość przy deklaracji, bez tego będzie błąd kompilacji (w C# będzie tylko warning)

1

Android to temat rzeka. Przez tydzień nie da się opanować podstaw. Właśnie kończę oficjalny kurs. Jest on dla początkujących programistów, więc nauka metodą małych kroków. Google powinno stworzyć też kurs dla zaawansowanych, aby od razu uczyć dobrych praktyk, tak jak powinno się budować aplikacje i rozszerzać jedną aplikację zamiast dwudziestu małych. Byłoby o wiele szybciej. Czeka mnie jeszcze nauka API Androida.

Jest też osobny kurs dla Compose, gdzie tematy się powtarzają:
https://developer.android.com/courses/jetpack-compose/course

Compose zawiera znacznie więcej bibliotek:
https://developer.android.com/jetpack/androidx/explorer

Pełna dokumentacja Compose
https://developer.android.com/jetpack/compose/documentation

Czy opłaca się dalej uczyć Compose? Czy ta technologia ma przyszłość? Jeśli to nie będzie wieloplatformowe, to moim zdaniem szkoda czasu. Ale czego by się nie uczyć, to za kilka lat trzeba uczyć się czegoś nowego. Na uniwerku były warsztaty z pisania natywnych aplikacji na Windows Phone. Później w modzie były Cordova i PhoneGap. Potem Xamarin, który działał dość wolno. Dziś React Native i Flutter. Dlaczego nie PWA? Uniwersalne API, wieloplatformowe technologie, ale gigantom przynosiłoby to straty.

0

W google powinni się uczyć od MS. Jak MS zrobił.NET-a i WPF 20 lat temu to do tej pory niewiele się zmieniło z punktu widzenia programisty.
A w Google coraz to nowe biblioteki niekompatybilne z całym światem, albo jakieś atrapy bibliotek do MVVM-a które się nadają co najwyżej do aplikacji z 3 widokami.

0

To nie do końca prawda, bo .net core zerwał praktycznie kompatybilność ze starym .net framework. Wszystko trzeba było pisać od początku.

0

To jest jakiś wzorzec projektowy? Znalazłem taką wtyczkę do Android Studio.

https://github.com/levinzonr/jetpack-compose-ui-arch-plugin

Dla każdego komponentu generujemy 5 plików, wszystko warstwa UI. Jakie są zalety takiej architektury? Niestety nie ma dokumentacji, co do czego służy, gdzie wstrzyknąć ProvideKomponentActions, co ma być w ViewModel, a co w Coordinator. To trochę bardziej komponentowe podejście. W googlowskich przykładowych projektach jest 1 lub kilka ViewModel, nie ma żadnych koordynatorów, w RouteGraph bezpośrednio używamy konkretnych Composable i często ViewModele mają napchane dużo logiki, która powinna znajdować się w innych miejscach?

Możecie podrzucić projekty na GitHubie, gdzie Waszym zdaniem jest wszystko poprawnie poukładane.

Ale nie ma co rozmyślać nad architekturą. Klient się niecierpliwi, a ja nawet prostego demo nie mam do pokazania.

4

Ja wrzucę opinię, która w tym dziale raczej nie zdobędzie przesadnej popularności. Uważam, że aplikacje na Androida są koszmarnie przekombinowane. Nie wiem co masz zrobić, ale 90% aplikacji mobilnych, to (czasami lekko rozwinięte) OPA do uruchamiania na telefonach. Przeczytaj sobie o tym jakie są komponenty aplikacyjne (activity, service, content provider, broadcast receiver), szczególnie uważnie przeczytaj fragmenty o ich cyklu życia, bo z braku znajomości tego cyklu bierze się większość błędów.... Rozpisz sobie to co masz na te komponenty. Na 90% nie wyjdziesz poza activity, ale warto zerknąć na początku. Czasami wskoczy jakiś broadcast receiver, ale raczej z marszu, jak będziesz implementował np. notyfikacje.
W drugim kroku masz do ogarnięcia łączność ze światem - tworzysz sobie klienta http, który ma wstać razem z aplikacją, zrobić handshake, w razie czego w prosty sposób możesz dorzucić tu jakiś cache.
Kolejny komponent, to utrwalanie danych - też zwykła klasa, ma odpowiadać za zapis odczyt do bazy danych (tutaj uwaga - naprawdę, większość aplikacji mobilnych nie potrzebuje relacyjnej bazy danych, często wystarczy utrwalić 5 rekordów na krzyż w jakimś jsonie i go gdzieś trzymać...).
Pozostaje jeszcze kwestia wstrzykiwania zależności i tutaj kiedyś się używało Dagger'a, ale... w Androidzie, wszystko musi być osadzone w jednym z komponentów aplikacyjnych, a tych nie tworzysz, nie masz możliwości zmiany ich konstruktora, kończy się na wstrzykiwaniu pól i wywołaniu gdzieś metody daggera "hej wstrzyknij mi wszystkie pola z adnotacjami". Więc o jakimkolwiek sensownym IoC nie ma co marzyć. Jak ci się chce zgłębiać kolejną bibliotekę, to możesz, ale jak nadpiszesz sobie klasę Application i wstawisz w niej metody fabrykujące do komponentów, których potrzebujesz, to będzie działać, w dodatku będziesz wiedział jak działa i zaoszczędzisz dzień, czy 2 na zmuszaniu jakiejś biblioteki do działania. Warto za to przemyśleć jakiś event bus, czyli np. w jednym miejscu użytkownik pobiera dane na nowo, klient http jak je dostanie, to wysyła zdarzenie, wszystkie kontrolki, które powinny dostają powiadomienie i się odświeżają.

Na UI jak to we front endzie - pokazują się jakieś nowinki, ale po skumaniu jak działają layouty, odpaleniu widoku z xml+preview da się robić UI szybko. Jedna uwaga - trzeba się nauczyć robić komponenty, nie ma z tym dużo roboty, a dużo prościej się w tym kodzie odnaleźć. Nie wiem jak dużo daje Jetpack, bo wyszedłem z Androida zanim się pojawił, ale jak już napisałem - z XML da się żyć.

Rzeczy na które na 100% się nadziejesz - nic co wykorzystuje komunikację http, albo może trwać dłużej nie ma szansy zadziałać na głównym wątku. Albo się nie skompiluje, albo będzie przypadkowo naparzać błędami u użytkowników. więc znowu kwestia wyboru... RxJava albo androidowy Handler. Znowu - moja wiedza jest tutaj przestarzała, od ~5 lat nie dotykałem Androida, ale wcześniej nawet sporo, jeszcze przed pojawieniem się pierwszych urządzeń.

MVVM, to w skrócie mapowanie widoku na model. Opisujesz każde pole na widoku, jak ma się mapować na model, jak zmienisz model i powiadomisz widok, to sobie te dane zaciągnie, jak widok coś zmieni, to też zrobi update na modelu. Nie potrzeba pisać z łapy model.setWhatever(mojaKontrolka.getText()). W Compose masz to już z tego co widzę "wbudowane", co może być jakimś argumentem.

Pytanie z tematu wydaje mi się równie bezcelowe jak zapytanie frontendowców "react czy angular"...

0

@Shiba Inu: Popatrz jeszcze na Fluttera i flutter bloc: https://bloclibrary.dev/#/

Na Githubie są przykłady także bardziej złożone. Architektura dużo bardziej sensowna niż to, co jest w natywnym Androidzie. Co do JetpackCompose to nikt ci za wiele tu nie powie, bo nikt nic większego w tym nie pisał.

0

W bardziej złożonych aplikacjach nie obejdzie się bez DI. W Springu i w Angularze jest to świetnie rozwiązane. ApplicationContext to tak faktycznie kontener zależności.

Mam wątpliwości do MVVM. Zdaje się, że ViewModel to zbędna warstwa abstrakcji i wrzucana jest tam logika biznesowa, która powinna znaleźć się gdzie indziej. Kiedy przeglądam przykłady, to raz jest 1 ViewModel na cały projekt, innym razem każdy komponent ma swój. W przypadku prostych komponentów nie wystarczy rememberSaveable()?

0

@Shiba Inu: Trochę nie moja bajka, ale z tego co jest napisane w aplikacji, rememberSaveable powoduje jedynie zapamiętanie stanu widoku i odtworzenie go po zmianie konfiguracji. Zmiana konfiguracji, to np. zmiana orientacji obiektu. W takich przypadkach, widok jest niszczony i tworzony od początku, następnie wypełniany stanem.

Czy MVVM to zbędna warstwa abstrakcji? Nie sądzę. Alternatywą jest pisanie gdzieś mappera pomiędzy każdą kontrolką z widoku a jakimś polem, które ma przyjąć jej wartość i w drugą stronę. W dodatku o ile tego nie poprawiono, to dostęp z kodu do tych kontrolek widoku nie jest wcale prosty i przyjemny. Pisanie nie jest więcej niż robiąc to "prosto", a porządek dużo większy.

0

Po zbudowaniu wyszło koło 6 MB, z czego większość to klasy Jetpack Compose. Kotlin to niewielki narzut. Tak więc jeśli aplikacja ma zajmować bardzo mało miejsca, to należy pisać w starym stylu. Jeśli chodzi o wydajność, to trzeba by przeprowadzić testy. Compose korzysta z API Androida niskopoziomowo.

0
Shiba Inu napisał(a):

Mam wątpliwości do MVVM. Zdaje się, że ViewModel to zbędna warstwa abstrakcji i wrzucana jest tam logika biznesowa, która powinna znaleźć się gdzie indziej. Kiedy przeglądam przykłady, to raz jest 1 ViewModel na cały projekt, innym razem każdy komponent ma swój. W przypadku prostych komponentów nie wystarczy rememberSaveable()?

  1. "Nie grzesz" :) Nie jest to zbędna warstwa. MVVM to moim zdaniem jeden z najlepszych wzorców projektowych jakie powstały. Największą zaletą jest to, że odprzęga całkowicie logikę aplikacji (model) od interfejsu. Im bardziej potniesz aplikację na warstwy tym łatwiej jest testować aplikację i szukać ew. bugów.
  2. Nie powinno się tam wrzucać żadnej logiki biznesowej. Logika aplikacji powinna znajdować się w modelu, który zawiera zwykłe klasy/obiekty (POJO/POCO). ViewModel jest tylko modelem widoku. Czymś czym jest ORM dla bazy danych. Takie rzeczy jak wkładanie logiki do ViewModelu można robić w aplikacjach które mają kilka widoków które nie współdzielą ze sobą funkcjonalności.
0
Kamil A napisał(a):

MVVM to moim zdaniem jeden z najlepszych wzorców projektowych jakie powstały. Największą zaletą jest to, że odprzęga całkowicie logikę aplikacji (model) od interfejsu. Im bardziej potniesz aplikację na warstwy tym łatwiej jest testować aplikację i szukać ew. bugów.

Zgodzę się co do testowalności, natomiast często ViewModel jest nadużywany. Inny ciekawy przypadek w oficjalnych przykładowych apkach to wielki potężny AppState zawierający NavController i mnóstwo metod, coś jak wielki globalny kontener, który sam w sobie jest modelem dla całej aplikacji. Raczej antywzorzec.

Nigdzie nie mogę znaleźć przykładu, jak prawidłowo trzymać sesję użytkownika i ją zapamiętać. Na razie wrzucę do SharedPreferences i będę trzymać zalogowanego użytkownika w AppViewModel (u mnie to viewModel dla głównego Composable, który decyduje, czy wyświetlić ekran logowania, czy przekazać piłkę do NavigationGraph). W jednym z tutoriali obiekt User jest przekazywany przez CompositionLocal do podrzędnych komponentów (bo wiele z nich musi mieć dostęp do informacji o zalogowanym użytkowniku).

Jeśli chodzi o wydajność, to testuję na budżetowym telefonie i działa to niewiele szybciej od apek stworzonych w React Native. Jetpack ręcznie buduje interfejs za pomocą niskopoziomowego API Androida i instrukcji do wykonania jest znacznie więcej. Musi też przerysować po każdej zmianie stanu.

0
Shiba Inu napisał(a):

Nigdzie nie mogę znaleźć przykładu, jak prawidłowo trzymać sesję użytkownika i ją zapamiętać. Na razie wrzucę do SharedPreferences i będę trzymać zalogowanego użytkownika w AppViewModel (u mnie to viewModel dla głównego Composable, który decyduje, czy wyświetlić ekran logowania, czy przekazać piłkę do NavigationGraph). W jednym z tutoriali obiekt User jest przekazywany przez CompositionLocal do podrzędnych komponentów (bo wiele z nich musi mieć dostęp do informacji o zalogowanym użytkowniku).

Nie wiem czy to jest prawidłowo, ale ja mam zrobione takie repozytorium singleton przechowujące LiveData .

Kod w Kotlin poniżej.
Oczywiście przed użyciem dobrze by było podmienić Int na jakąś klasę User albo coś w rodzaju UserAuthenticationData z warstwy aplikacji. W kodzie poniżej jest po prostu Int.

package pl.mojafirma.mojaaplikacja.viewmodel

import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData

class CurrentUserRepository private constructor() {
    private val TAG = "MojaAplikacja" + this.javaClass.simpleName

    private val _user = MediatorLiveData<Int>()
    val user: LiveData<Int> = _user

    fun addDataSource(user: LiveData<Int>?) = _user.addSource(user!!, _user::setValue)
    fun removeDataSource(user: LiveData<Int>?) = _user.removeSource(user!!)
    fun setuser(user: Int) { _user.value = user; Log.d(TAG, "user set to $user") }

    companion object {
        private val INSTANCE = CurrentuserRepository()
        fun instance(): CurrentuserRepository = INSTANCE
    }
}

Później usera można ustawić tak:

import pl.mojafirma.mojaaplikacja.viewmodel.CurrentUserIdRepository // ups, repozytorium powinno być w paczce repository a nie viewmodel
// ... 
CurrentUserIdRepository.instance().setUserId(185)

Umieścić w ViewModel tak:

import pl.mojafirma.mojaaplikacja.viewmodel.CurrentUserIdRepository // ups, repozytorium powinno być w paczce repository a nie viewmodel
// ...
fun getUserId(): LiveData<Int> = CurrentUserIdRepository.instance().userId

i we fragmencie obserwować tak:

getUserId().observe(viewLifecycleOwner) {
    Log.d(TAG, "UserId changed observed in a fragment")
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1