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.

Ta interakcja wymaga włączonego JavaScriptu.

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.

PlikRola w ćwiczeniu
MainPage.xamlWygląd strony lub kontrolki
MainPage.xaml.csLogika 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.

MainPage.xaml — etap tymczasowyxaml
<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>
  1. 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

RodzajCharakterystykaJęzyki i środowiska
Natywna dla danej platformyProjekt korzysta z API i kontrolek konkretnego systemu.Android: Kotlin/Java; iOS: Swift/Objective-C.
WebowaInterfejs 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 WebViewInterfejs 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.
Cross-platform mówi o współdzieleniu kodu, a hybrydowa z WebView o sposobie wykonania interfejsu. Nie są to rozłączne etykiety: aplikacja hybrydowa może być wieloplatformowa. Sam wspólny kod nie oznacza WebView.

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.

App.xaml.cscsharp
namespace MojaAplikacja;

public partial class App : Application
{
    public App() => InitializeComponent();
    protected override Window CreateWindow(IActivationState? activationState)
        => new Window(new NavigationPage(new MainPage()));
}
  1. CreateWindow Tworzy okno aplikacji. NavigationPage jest kontenerem zwykłych stron i daje przycisk powrotu; nie łączymy go z Shell.
  2. 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.

MainPage.xamlxaml
<?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>
  1. <ContentPage ... x:Class="MojaAplikacja.MainPage"> Pojedyncza strona aplikacji, powiązana z klasą w pliku .xaml.cs.
  2. VerticalStackLayout Padding="24" Spacing="12" Elementy jeden pod drugim, z marginesem wewnętrznym i odstępem między elementami.
  3. x:Name Etykiety 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.

MainPage.xaml.cscsharp
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 }
        });
    }
}
  1. protected override void OnAppearing() Strona pojawia się na ekranie. Dobre miejsce na wczytanie lub odświeżenie danych.
  2. protected override void OnDisappearing() Strona znika. Dobre miejsce na zapis stanu i zatrzymanie kosztownych operacji, np. timera.
  3. base.OnAppearing() Wywołuje oryginalną implementację klasy bazowej. To nawyk przy nadpisywaniu metod frameworka, żeby nie zepsuć jego pracy.
  4. _liczbaPojawien++ Licznik pojawień: rośnie przy każdym powrocie na stronę, więc widać, że OnAppearing wykonuje 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
Tak nie
„Każdy wspólny kod na wiele systemów to aplikacja hybrydowa z WebView.”

Mylisz sposób współdzielenia kodu ze sposobem renderowania interfejsu.

Tak
„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
Tak nie
Aplikacja pobiera dane i zakłada, że połączenie jest zawsze dostępne.

Bez zasięgu aplikacja się wywraca albo zostawia pusty ekran.

Tak
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
Tak nie
// Założenie: OnDisappearing zawsze wykona się przed zabiciem procesu.

System może zakończyć proces bez tej ścieżki; dane mogą zostać utracone.

Tak
// 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.

Oczekiwany rezultat
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.

Ta interakcja wymaga włączonego JavaScriptu.

Podsumowanie

Co warto zapamiętać

  1. Natywna, webowa i hybrydowa z WebView opisują sposób wykonania. Wieloplatformowa oznacza możliwość współdzielenia kodu.
  2. Standardowe MAUI używa platformowych odpowiedników kontrolek, a Flutter zwykle rysuje własny interfejs.
  3. Android Activity ma callbacki m.in. onCreate, onStart, onResume, onPause, onStop, onRestart i onDestroy. Nie jest to zawsze jeden niezmienny łańcuch.
  4. OnAppearing/OnDisappearing dotyczą strony; Window.Stopped/Resumed i cykl Androida dotyczą innych warstw. Nie gwarantują zapisu tuż przed zakończeniem procesu.
  5. 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ę →
Źródła i dalsza nauka