Aplikacje mobilne · Wprowadzenie
Aplikacje mobilne: rodzaje i cykl życia
Zanim napiszesz pierwszą linijkę kodu, musisz wiedzieć, czym jest aplikacja mobilna, jakie ma rodzaje i jak przechodzi przez swój cykl życia. To fundament INF.04.6 i częsty temat pytań teoretycznych na egzaminie. Cały dział opiera się na .NET MAUI, jednej aplikacji w C# na Androida, iOS, Windows i macOS.
- około 40 minut
- .NET MAUI · rodzaje aplikacji · cykl życia
- INF.04.6
Po tej lekcji: odróżnić interfejs natywny, webowy i hybrydowy z WebView, wyjaśnić wieloplatformowość oraz odróżnić widoczność strony od cyklu aplikacji.
Licznik powrotów na stronę
Wracasz do aplikacji z innego ekranu i chcesz zobaczyć aktualne dane. Sprawdzimy, dlaczego utworzenie strony i jej ponowne pokazanie to dwa różne zdarzenia.
Najpierw uruchomisz mały ekran. Potem połączysz go z kodem i sprawdzisz konkretne wyniki. Dodatki wykonuj dopiero, gdy wersja podstawowa działa. Quiz i oceniane zadania pozostają w biurku po zalogowaniu.
3 · Stany aplikacji
Callbacki Activity — co oznaczają?
To przegląd callbacków Android Activity, nie liniowy harmonogram aplikacji i nie cykl strony MAUI. C# używa nazw OnCreate itd., dokumentacja Androida onCreate itd. Przy powrocie po OnStop dochodzą OnRestart i OnStart. System może zakończyć proces bez wywołania OnDestroy.
Najpierw przewidź, potem sprawdź: W przeglądzie callbacków wybierz OnCreate, a potem OnResume. Porównaj powód obu wywołań. To model Activity Androida; nie utożsamiaj go z OnAppearing strony MAUI.
Przykład: uruchomienie (OnCreate → OnStart → OnResume), chwilowy skok do innej aplikacji (OnPause → OnStop), powrót (OnRestart → OnResume), zamknięcie (OnDestroy). Model pomaga zobaczyć mechanizm; właściwą aplikację uruchomisz z plików poniżej.
1. Przygotuj miejsce pracy
Co dodajesz, a co podmieniasz?
Stronę dodaj przez Projekt → Dodaj → Nowy element → .NET MAUI ContentPage (XAML). Powstaje para .xaml i .xaml.cs. Dla ContentView wybierz szablon ContentView; dla modeli i serwisów zwykłą klasę. Jeśli plik już istnieje, podmień wskazaną zawartość — nie twórz drugiej klasy o tej samej nazwie.
| Plik | Rola w ćwiczeniu |
|---|---|
| MainPage.xaml | Wygląd strony lub kontrolki |
| MainPage.xaml.cs | Logika i obsługa danych |
Zanim uruchomisz: trzy połączenia
x:Class="MojaAplikacja.NazwaStrony" w XAML musi zgadzać się z namespace MojaAplikacja i nazwą klasy C#. InitializeComponent() tworzy kontrolki opisane w XAML.
x:Name="PoleImie" daje kodowi C# dostęp przez PoleImie.Text. Z kolei Clicked="Zapisz_Clicked" wskazuje metodę o tej nazwie w pliku .xaml.cs. Sam napis przycisku w Text niczego nie podpina.
Gdy dodajesz XAML z obsługą zdarzeń, od razu uzupełnij też odpowiadający C#. Uruchamiaj dopiero po skończeniu oznaczonej pary plików; brakujący handler nie jest błędem środowiska.
2. Uruchom sam wygląd — jeszcze bez logiki
W świeżym projekcie zastąp MainPage.xaml poniższym ekranem. W MainPage.xaml.cs zachowaj konstruktor z InitializeComponent(); usuń szablonowy licznik i OnCounterClicked, bo nie ma ich już w XAML. Na tym etapie App i AppShell pozostają z szablonu. To pełny, tymczasowy XAML — później świadomie go podmienisz, nie dokleisz do drugiego ContentPage.
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MojaAplikacja.MainPage">
<VerticalStackLayout Padding="24" Spacing="14">
<Label Text="Czy strona uruchamia się raz?" FontSize="24" />
<Label Text="Za chwilę dodasz licznik powrotów." />
</VerticalStackLayout>
</ContentPage>
- Pierwsza próba Uruchom. Zobaczysz kontrolki, ale przyciski bez Clicked jeszcze nic nie robią. Sprawdź rozmiar i kolejność elementów. Zatrzymaj aplikację przed następnym etapem.
Zacznijmy od telefonu
Aplikacja, która „pamięta”
Gdy w trakcie czegoś wracasz na chwilę do przeglądarki albo mapy, aplikacja „pamięta”, gdzie skończyłeś. Nie logujesz się ponownie ani nie wracasz na początek. To zasługa cyklu życia: aplikacja zapisała stan, gdy zeszła w tło, i odtworzyła go po powrocie.
Dla programisty to ważne, bo aplikacja mobilna nie żyje sama. System ją usypia, wznawia i zamyka, żeby oszczędzać baterię i pamięć.
1 · Sposób działania i wspólny kod
Natywna, webowa, hybrydowa i wieloplatformowa
| Rodzaj | Charakterystyka | Języki i środowiska |
|---|---|---|
| Natywna dla danej platformy | Projekt korzysta z API i kontrolek konkretnego systemu. | Android: Kotlin/Java; iOS: Swift/Objective-C. |
| Webowa | Interfejs działa w przeglądarce. Możliwości sprzętowe zależą od API i zgód; PWA może działać offline i dać się zainstalować. | HTML/CSS/JS, PWA. |
| Hybrydowa z WebView | Interfejs webowy działa w natywnej aplikacji; funkcje urządzenia są udostępniane przez mosty lub wtyczki. | Ionic z Capacitor, Cordova; MAUI Blazor Hybrid to wariant webowy wewnątrz MAUI. |
| Wieloplatformowa (cross-platform) | Współdzielenie kodu między systemami; to nie jedna metoda renderowania interfejsu. | Standardowe MAUI odwzorowuje kontrolki na platformowe; React Native również używa widoków natywnych; Flutter zwykle sam rysuje UI własnym silnikiem. |
4 · Od pomysłu do sklepu
Pięć etapów produkcji aplikacji mobilnej
Planowanie i projektowanie (cel, grupa docelowa, platforma, interfejs pod małe ekrany) → tworzenie (kod i funkcje sprzętowe: GPS, aparat, powiadomienia) → testowanie (różne urządzenia i rozdzielczości, wydajność, uprawnienia, tryb offline) → wdrożenie (publikacja w Google Play lub App Store i zatwierdzenie przez sklep) → eksploatacja i konserwacja (analityka, aktualizacje, opinie użytkowników).
Aplikacje mobilne są zwykle stanowe: przechowują dane i stan działania. Mogą działać online i offline, a po odzyskaniu internetu synchronizują dane. Do publikacji wrócimy w ostatnich lekcjach działu.
3. Wskaż stronę startową ćwiczenia
Po dodaniu docelowych stron podmień App.xaml.cs na poniższy. App.xaml zostaje z szablonu. Od tej chwili startuje MainPage, a nie wcześniejszy tymczasowy MainPage z AppShell. Uzupełnij jej pliki w kolejnych etapach, zanim ponownie uruchomisz projekt.
namespace MojaAplikacja;
public partial class App : Application
{
public App() => InitializeComponent();
protected override Window CreateWindow(IActivationState? activationState)
=> new Window(new NavigationPage(new MainPage()));
}
CreateWindowTworzy okno aplikacji. NavigationPage jest kontenerem zwykłych stron i daje przycisk powrotu; nie łączymy go z Shell.new MainPage()Tworzy instancję docelowej strony. Aby testować drugi niezależny przykład, zatrzymaj program, zmień tylko ten typ i uruchom ponownie.
4. Połącz wygląd z działaniem
Teraz zbuduj docelowy przykład. Pełne pliki poniżej zastępują swoje wcześniejsze wersje. Przeczytaj opis nad kodem i objaśnienia pod nim; potem sprawdź przepływ danych, nie tylko brak czerwonych podkreśleń.
Gdy przykład ma kilka plików zależnych od siebie, najpierw dodaj wszystkie wskazane typy, a potem uruchom całość. Ustaw breakpoint w obsłudze głównego przycisku i prześledź jedną próbę.
Budowa krok po kroku
MainPage.xaml
Dwie etykiety mają x:Name, ponieważ będą aktualizowane z C#. Dodany przycisk otwiera ekran próbny; bez niego sam licznik powrotów nie miałby tu jak się zmienić.
Prosta strona z dwiema etykietami. W MAUI zamiast Window jest ContentPage, a pionowy układ daje VerticalStackLayout.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MojaAplikacja.MainPage"
Title="Cykl życia">
<VerticalStackLayout Padding="24" Spacing="12">
<Label x:Name="EtykietaStan" Text="Strona jeszcze nie pojawiła się na ekranie." FontSize="18" />
<Label x:Name="EtykietaLicznik" Text="Pojawień się: 0" />
<Button Text="Otwórz ekran próbny" Clicked="OtworzProbe_Clicked" />
</VerticalStackLayout>
</ContentPage>
<ContentPage ... x:Class="MojaAplikacja.MainPage">Pojedyncza strona aplikacji, powiązana z klasą w pliku.xaml.cs.VerticalStackLayout Padding="24" Spacing="12"Elementy jeden pod drugim, z marginesem wewnętrznym i odstępem między elementami.x:NameEtykiety mają nazwy, bo kod je zmienia.
Budowa krok po kroku
MainPage.xaml.cs
Przeczytaj kolejno konstruktor, OnAppearing i OnDisappearing. Konstruktor tworzy stronę, a callbacki opisują jej widoczność. Nawigacja testowa daje powtarzalny sposób opuszczenia i powrotu.
OnAppearing i OnDisappearing dotyczą widoczności strony. Nie są pełnym odpowiednikiem cyklu aplikacji Androida ani gwarancją wywołania przy zamknięciu procesu. Zapisujemy czas do pola i pokazujemy go po powrocie; komunikat w ukrytej etykiecie byłby niewidoczny. Do cyklu okna służą m.in. Window.Stopped/Resumed; ważny stan zapisuj również przy zatwierdzaniu zmian.
namespace MojaAplikacja;
public partial class MainPage : ContentPage
{
private int _liczbaPojawien;
private DateTime? _ostatnieZnikniecie;
public MainPage() => InitializeComponent();
protected override void OnAppearing()
{
base.OnAppearing();
_liczbaPojawien++;
EtykietaLicznik.Text = $"Pojawień: {_liczbaPojawien}";
EtykietaStan.Text = _ostatnieZnikniecie is DateTime czas
? $"Ostatnio opuszczono stronę o {czas:HH:mm:ss}."
: "Pierwsze pojawienie strony.";
}
protected override void OnDisappearing()
{
base.OnDisappearing();
_ostatnieZnikniecie = DateTime.Now;
System.Diagnostics.Debug.WriteLine("Strona przestaje być widoczna.");
}
private async void OtworzProbe_Clicked(object sender, EventArgs e)
{
await Navigation.PushAsync(new ContentPage
{
Title = "Ekran próbny",
Content = new Label { Text = "Wróć strzałką wstecz.", Margin = 24 }
});
}
}
protected override void OnAppearing()Strona pojawia się na ekranie. Dobre miejsce na wczytanie lub odświeżenie danych.protected override void OnDisappearing()Strona znika. Dobre miejsce na zapis stanu i zatrzymanie kosztownych operacji, np. timera.base.OnAppearing()Wywołuje oryginalną implementację klasy bazowej. To nawyk przy nadpisywaniu metod frameworka, żeby nie zepsuć jego pracy._liczbaPojawien++Licznik pojawień: rośnie przy każdym powrocie na stronę, więc widać, żeOnAppearingwykonuje się wielokrotnie, a konstruktor tylko raz.
5. Odbiór: czy naprawdę działa?
Wykonaj próby w swojej aplikacji, nie tylko w modelu na stronie. Zaznaczaj dopiero po sprawdzeniu wyniku. Funkcje urządzenia wymagają testu na właściwej platformie.
7 · Czego unikać
Trzy błędy w myśleniu o aplikacji mobilnej
Cross-platform nie oznacza automatycznie WebView
„Każdy wspólny kod na wiele systemów to aplikacja hybrydowa z WebView.”Mylisz sposób współdzielenia kodu ze sposobem renderowania interfejsu.
„Standardowe MAUI jest wieloplatformowe i używa kontrolek platformowych. MAUI Blazor Hybrid używa interfejsu webowego.”Zawsze sprawdź technologię UI, zamiast wnioskować wyłącznie z języka lub liczby systemów.
Założenie, że zawsze jest internet
Aplikacja pobiera dane i zakłada, że połączenie jest zawsze dostępne.Bez zasięgu aplikacja się wywraca albo zostawia pusty ekran.
Wykryj brak połączenia, pokaż komunikat i zapisz dane lokalnie do późniejszej synchronizacji.Dobra aplikacja mobilna przewiduje tryb offline.
Zapis wyłącznie przy znikaniu strony
// Założenie: OnDisappearing zawsze wykona się przed zabiciem procesu.System może zakończyć proces bez tej ścieżki; dane mogą zostać utracone.
// Zapisuj ważną zmianę przy zatwierdzeniu; obsługę cyklu okna traktuj jako dodatkową.Cykl strony i cykl aplikacji nie są tym samym. OnDisappearing nie jest zdarzeniem zamknięcia aplikacji.
Ćwiczenie z pomocą · samodzielna praca
6. Mała zmiana, którą zrobisz samodzielnie
Dodaj etykietę z godziną ostatniego pojawienia strony.
Dodaj etykietę z godziną ostatniego pojawienia strony. Dotychczasowe działanie ma pozostać poprawne.
? Potrzebujesz pomocy? Rozwiązuj krok po kroku.
Krok 1 — pokaż podpowiedź
Dodaj w stosie Label z x:Name="CzasPowrotuLabel".
Krok 2 — pokaż podpowiedź
W OnAppearing, po base.OnAppearing(), ustaw jego Text na DateTime.Now.ToString("HH:mm:ss").
Krok 3 — pokaż podpowiedź
Przejdź na ekran próbny, odczekaj kilka sekund i wróć. Porównaj godzinę.
Otwórz tylko tyle podpowiedzi, ile potrzebujesz. Po każdym kroku wróć do zadania i sprawdź wynik.
2 · Rozpoznaj rodzaj
Rozpoznaj sposób zbudowania aplikacji
Cztery opisy aplikacji. Wskaż rodzaj.
Podsumowanie
Co warto zapamiętać
- Natywna, webowa i hybrydowa z WebView opisują sposób wykonania. Wieloplatformowa oznacza możliwość współdzielenia kodu.
- Standardowe MAUI używa platformowych odpowiedników kontrolek, a Flutter zwykle rysuje własny interfejs.
- Android Activity ma callbacki m.in. onCreate, onStart, onResume, onPause, onStop, onRestart i onDestroy. Nie jest to zawsze jeden niezmienny łańcuch.
- OnAppearing/OnDisappearing dotyczą strony; Window.Stopped/Resumed i cykl Androida dotyczą innych warstw. Nie gwarantują zapisu tuż przed zakończeniem procesu.
- Aplikacja mobilna jest stanowa i powinna działać także offline.
Dalej na swoim koncie
Rozgrzewki, quiz i zadania są w biurku ucznia.
Teoria jest otwarta dla wszystkich. Żeby rozwiązywać zadania, zapisywać szkice i widzieć swój postęp, zaloguj się.
Zaloguj się →