Skip to content

25 • Architektura a komponenty Android aplikací

Architektura, Kernel, ART, Activity, Service, Broadcast Receiver, Content Provider, Sandbox, Manifest, práva, Intent, Compose, MVVM, Lifecycle


Co je Android

Android je open-source mobilní operační systém spravovaný Googlem a koalicí Open Handset Alliance. Postavený na Linuxovém kernelu. Běží na telefonech, tabletech, hodinkách (Wear OS), TV (Android TV), autech (Android Auto / Automotive).

První verze 2008 (Android 1.0), aktuálně Android 15 (vydaný 2024) a Android 16 (2025). Verze se dříve pojmenovávaly podle dezertů (Cupcake, Donut, Eclair...), od Androidu 10 už jen čísly.

Klíčové vlastnosti

Vývojové jazykyKotlin (preferovaný od 2017), Java (legacy), C/C++ (NDK pro výkon)
IDEAndroid Studio (oficiální, postavený na IntelliJ)
Build systémGradle
DistribuceGoogle Play Store, sideloading APK, F-Droid
Open sourceAOSP (Android Open Source Project), z toho čerpají custom ROMy (LineageOS, GrapheneOS, Evolution X)

Architektura Android platformy

Android je zásobník vrstev. Každá vrstva poskytuje služby vrstvě nad ní a abstrahuje od té pod ní.

image.png

Vrstvy zdola nahoru

1. Linux Kernel

Základ celé platformy. Spravuje paměť, procesy, drivery hardwaru. Verze kernelu se mírně liší od mainline Linux kernelu (Android přidává specifické úpravy: Binder IPC, wakelocks, atd.). Stará se o bezpečnost na úrovni procesů (každá aplikace má vlastní UID, viz Sandbox).

2. HAL (Hardware Abstraction Layer)

Standardní rozhraní mezi hardwarem a vyššími vrstvami. Aplikace volá "fotit fotku", HAL přeloží to volání na konkrétní driver kamery.

3. Android Runtime + Native Libraries

ART spouští bytekód aplikací. Vedle něj C/C++ knihovny: OpenGL pro grafiku, SQLite pro databáze, WebKit pro WebView, libc, SSL.

4. Application Framework

Vrstva, se kterou pracují vývojáři aplikací. Java/Kotlin API pro Activity Manager, Notifikace, Location, Content Providers, atd.

5. Applications

Samotné aplikace, jak systémové (Kontakty, Telefon, Gmail) tak third-party.


ART (Android Runtime)

ART je virtuální stroj Androidu, nástupce Dalvik VM (od Android 5.0 Lollipop, 2014). Spouští bytekód aplikací ve specifickém formátu DEX (Dalvik Executable).

Cesta od kódu k běžící aplikaci

Zdrojový kód (.kt, .java)
        ↓     Kompilace (kotlinc / javac)
 Java bytecode (.class)
      ↓        D8 / R8 dexer
 DEX soubor (.dex)

 Aplikace nainstalovaná (.apk obsahuje DEX)
      ↓         ART
 AOT + JIT kompilace do strojového kódu pro daný CPU

 Běžící aplikace

ART vs Dalvik

Dalvik (do Androidu 5.0)ART (od Androidu 5.0)
KompilaceJIT (Just-In-Time, za běhu)Hybrid AOT + JIT
InstalaceRychlejšíPomalejší (AOT kompiluje)
Spuštění aplikacePomalejší (JIT překládá)Rychlejší (už zkompilováno)
Paměťová stopaMenšíVětší (uložený AOT kód)

Od Androidu 7.0 ART používá profile-guided AOT: nejdřív aplikace běží přes JIT, ART sleduje které části se používají často, a postupně je v klidu (nabíjení v noci) překompiluje AOT. Nejlepší obou světů.


Sandbox

Každá aplikace běží ve vlastním sandboxu: izolovaném prostředí. Toto je zděděno z Linuxového user systému.

┌─────────────────────────────┐
│  App A (UID 10067)          │
│  ├─ vlastní proces           │
│  ├─ vlastní paměť            │
│  └─ vlastní filesystem       │
│     /data/data/com.app.a/    │
└─────────────────────────────┘

┌─────────────────────────────┐
│  App B (UID 10069)          │
│  ├─ vlastní proces (jiný)    │
│  ├─ vlastní paměť (jiná)     │
│  └─ vlastní filesystem       │
│     /data/data/com.app.b/    │
└─────────────────────────────┘

App A NEMŮŽE číst data App B (jiné UID, Linux ochrana)

Důsledky

  • Bezpečnost: jedna aplikace nemůže šahat do druhé bez explicitního souhlasu
  • Crash izolace: pád jedné aplikace neshodí systém
  • Sdílení dat vyžaduje explicitní mechanismus: Content Provider, Intent, IPC

Důležitá poznámka: root přístup obchází sandbox z pozice systému. Aplikaci s rootem nelze sandboxem omezit. Proto root práva znamenají věřit konkrétní aplikaci, že je nezneužije.


Čtyři základní komponenty Android aplikace

1. Activity

Activity je jedna obrazovka s UI. Uživatel vidí a interaguje s jednou Activity najednou. Aplikace má typicky několik Activities (LoginActivity, MainActivity, DetailActivity).

kotlin
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MaterialTheme {
                MainScreen()
            }
        }
    }
}

V moderním Android vývoji se trend posouvá k Single Activity Architecture: jedna Activity, navigace mezi obrazovkami pomocí Navigation Component a Fragmentů (nebo Compose composables).

2. Service

Service běží na pozadí bez UI. Slouží pro dlouhotrvající úlohy.

TypPopisPříklad
Foreground ServiceS povinnou viditelnou notifikacíPřehrávání hudby, navigace, fitness tracker
Background ServiceBez UI (omezené od Android 8+)Sync dat (krátké úlohy)
Bound ServiceJiná komponenta se k němu připojí (IPC)Sdílená logika mezi appkami
kotlin
class MusicService : Service() {
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        // Foreground service vyžaduje notifikaci
        startForeground(NOTIFICATION_ID, buildNotification())
        // přehrávat hudbu
        return START_STICKY  // restart pokud OS service zabije
    }
}

3. Broadcast Receiver

Broadcast Receiver naslouchá systémovým nebo aplikačním broadcastům: zprávám, které posílá OS nebo jiná aplikace.

Systém Android
    │  "wifi_state_changed"
    │  "battery_low"
    │  "screen_on"

Broadcast Receiver → reaguje (sync data, zobrazí notifikaci)
kotlin
class NetworkReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == ConnectivityManager.CONNECTIVITY_ACTION) {
            val isConnected = checkConnection(context)
            // ...
        }
    }
}

4. Content Provider

Content Provider umožňuje aplikaci poskytovat data jiným aplikacím přes standardní rozhraní (URI a CRUD operace).

Tvoje App ──── ContentResolver ──── Content Provider ──── Jiná App
                                  (např. Contacts Provider)

                                  content://contacts/people

Příklady systémových Content Providers:

ProviderCo poskytujeURI
ContactsContractKontaktycontent://contacts/contacts
MediaStoreFotky, videa, hudbacontent://media/external/images/media
CalendarContractKalendářcontent://com.android.calendar/events
DocumentsSouborycontent://documents/...
kotlin
// Čtení kontaktů
val cursor = contentResolver.query(
    ContactsContract.Contacts.CONTENT_URI,
    null, null, null, null
)

Souhrn 4 komponent

KomponentaUI?ÚčelPříklad
ActivityAnoJedna obrazovkaLogin, Detail produktu
ServiceNeBackground prácePřehrávání hudby, navigace
Broadcast ReceiverNeReakce na událostiWifi zapnuto, baterie nízká
Content ProviderNeSdílení datKontakty, Media

AndroidManifest.xml

Manifest je povinný konfigurační soubor. Říká systému, jakou má aplikace strukturu, co potřebuje a jak ji spouštět. Bez správné registrace v manifestu komponenta neexistuje.

xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">

    <!-- Oprávnění -->
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <!-- Minimální SDK -->
    <uses-sdk
        android:minSdkVersion="24"
        android:targetSdkVersion="34" />

    <application
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">

        <!-- Aktivita s launcher kategorií = vstupní bod -->
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- Druhá aktivita, nedostupná zvenku -->
        <activity android:name=".DetailActivity" android:exported="false" />

        <!-- Service -->
        <service android:name=".MusicService" android:foregroundServiceType="mediaPlayback" />

        <!-- Broadcast Receiver -->
        <receiver android:name=".BootReceiver" android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

        <!-- Content Provider -->
        <provider
            android:name=".MyContentProvider"
            android:authorities="com.example.myapp.provider"
            android:exported="false" />

    </application>
</manifest>

Co manifest definuje

  • Všechny 4 komponenty (Activity, Service, Receiver, Provider)
  • Permissions: co aplikace potřebuje
  • minSdkVersion, targetSdkVersion: rozsah Android verzí
  • Ikona, název, téma
  • Intent filters: jaké intenty aplikace umí zpracovat
  • exported flag: jestli komponenta může být spuštěna z jiných aplikací (povinné od Android 12)

Práva (Permissions)

Android používá permission systém pro kontrolu přístupu k citlivým API a datům.

Kategorie permissions

TypSchváleníPříklady
NormalAutomaticky při instalaciINTERNET, ACCESS_NETWORK_STATE, VIBRATE
DangerousUživatel musí schválit za běhuCAMERA, READ_CONTACTS, ACCESS_FINE_LOCATION
SignatureJen aplikace podepsané stejným klíčemPro suite aplikací jednoho výrobce
SpecialSpeciální nastavení v SettingsSYSTEM_ALERT_WINDOW, WRITE_SETTINGS

Runtime permissions (od Android 6, 2015)

Dangerous permissions se neudělují při instalaci, ale v okamžiku, kdy aplikace funkci potřebuje. Uživatel vidí dialog a může povolit/odmítnout.

kotlin
// Kontrola, jestli permission je udělena
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
    != PackageManager.PERMISSION_GRANTED) {

    // Žádost o permission
    ActivityCompat.requestPermissions(
        this,
        arrayOf(Manifest.permission.CAMERA),
        REQUEST_CODE_CAMERA
    )
}

// V moderním Compose:
val permissionLauncher = rememberLauncherForActivityResult(
    ActivityResultContracts.RequestPermission()
) { granted ->
    if (granted) { /* spusť kameru */ }
}

Button(onClick = { permissionLauncher.launch(Manifest.permission.CAMERA) }) {
    Text("Otevřít kameru")
}

Specifika novějších Androidu

VerzeZměna
Android 6.0Runtime permissions zavedeny
Android 10Scoped Storage (omezený přístup k souborům)
Android 11One-time permissions (povolit "jen teď")
Android 13POST_NOTIFICATIONS (notifikace jsou nově dangerous)
Android 14Granulární galerie (vybrat jen některé fotky)

Intent

Intent je zpráva, která spouští komponentu nebo předává data mezi komponentami. Slovo znamená "záměr" (chci něco udělat).

Explicitní Intent

Znáš přesnou cílovou komponentu (vlastní Activity, vlastní Service).

kotlin
val intent = Intent(this, DetailActivity::class.java)
intent.putExtra("user_id", 69)
intent.putExtra("source", "main_screen")
startActivity(intent)

V DetailActivity:

kotlin
val userId = intent.getIntExtra("user_id", -1)
val source = intent.getStringExtra("source")

Implicitní Intent

Nevíš, která aplikace to zvládne. Systém najde všechny vhodné aplikace a buď přímo spustí, nebo zobrazí Intent Chooser (modální dialog s výběrem).

kotlin
// Otevřít URL: systém ukáže prohlížeče
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://spot.ax4.cz"))
startActivity(intent)

// Sdílet text: systém ukáže aplikace pro sdílení
val shareIntent = Intent(Intent.ACTION_SEND).apply {
    type = "text/plain"
    putExtra(Intent.EXTRA_TEXT, "Mrkni na SpotShare!")
}
startActivity(Intent.createChooser(shareIntent, "Sdílet přes..."))

// Vyfotit fotku: spustí výchozí kameru
val takePicture = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivity(takePicture)

Intent Filters v manifestu

Aplikace v manifestu deklaruje, jaké intenty umí zpracovat:

xml
<activity android:name=".ShareActivity">
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="text/plain" />
    </intent-filter>
</activity>

Toto registruje aplikaci jako kandidáta pro "sdílet text".

Activity Result API (moderní)

Stará metoda startActivityForResult + onActivityResult je deprecated. Moderní přístup:

kotlin
val cameraLauncher = registerForActivityResult(
    ActivityResultContracts.TakePicturePreview()
) { bitmap: Bitmap? ->
    // zpracuj fotku
}

Button(onClick = { cameraLauncher.launch(null) }) {
    Text("Vyfotit")
}

Activity Lifecycle

Activity prochází řadou callback metod podle stavu. Pochopení je klíčové pro správnou aplikaci.

CallbackKdy se voláCo dělat
onCreate()Activity se vytvoříInicializace UI, dat, ViewModelu
onStart()Activity je viditelnáStart UI animací
onResume()Uživatel interagujeStart kamery, GPS, senzorů
onPause()Příchozí jiná ActivityUložit stav, zastavit kameru
onStop()Activity zcela skrytáZastavit těžké operace
onRestart()Po stopu, před startemObnovení dat
onDestroy()Activity se ničíUvolnit zdroje

Typické scénáře

Spuštění aplikace:    onCreate → onStart → onResume
Minimalizace (Home):  onPause → onStop
Návrat do aplikace:   onRestart → onStart → onResume
Zavření aplikace:     onPause → onStop → onDestroy
Otevření jiné app:    onPause → onStop (a → onResume po návratu)

Configuration changes (rotace, dark mode)

Defaultně se Activity úplně zničí a vytvoří znovu při změně konfigurace (rotace, jazyk, dark/light mode).

Rotace telefonu:      onPause → onStop → onDestroy → onCreate → onStart → onResume

Proto je důležitý ViewModel, který tuto destrukci přežije:

kotlin
class MainViewModel : ViewModel() {
    val data = mutableStateListOf<User>()  // přežije rotaci

    init {
        loadData()
    }
}

Fragment (stručně)

Fragment je "mini Activity" - kus UI s vlastním lifecycle, který lze vložit do Activity. Klasicky se používal pro:

  • Tablet UI (dva fragmenty vedle sebe)
  • Recyklace UI komponent v různých Activity
  • Navigaci mezi obrazovkami v Single Activity Architecture

Dnes v Compose éře se používá méně, ale ještě existuje. Má vlastní lifecycle podobný Activity.

kotlin
class UserListFragment : Fragment(R.layout.fragment_user_list) {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        // ...
    }
}

MVVM architektura

MVVM (Model-View-ViewModel) je doporučená architektura Googlu pro Android aplikace.

Vrstvy

┌─────────────────────────────────────────┐
│             VIEW (UI)                   │
│      Activity / Compose / Fragment      │
│      "Co se zobrazuje uživateli"        │
└─────────────────────┬───────────────────┘
                      │ observuje state

┌─────────────────────────────────────────┐
│           VIEWMODEL                     │
│   - Drží UI state                       │
│   - Zpracovává user actions             │
│   - Volá Repository                     │
└─────────────────────┬───────────────────┘
                      │ volá

┌─────────────────────────────────────────┐
│              MODEL                      │
│   - Repository (abstrakce)              │
│   - Data sources:                       │
│     • API (Retrofit)                    │
│     • Database (Room)                   │
│     • Cache, SharedPrefs                │
└─────────────────────────────────────────┘

Kompletní příklad

kotlin
// MODEL (Repository)
class UserRepository(
    private val api: UserApi,
    private val dao: UserDao
) {
    suspend fun getUsers(): List<User> {
        return try {
            val users = api.fetchUsers()
            dao.insertAll(users)  // cache
            users
        } catch (e: Exception) {
            dao.getAll()  // fallback na lokální data
        }
    }
}

// VIEWMODEL
class UserViewModel(
    private val repository: UserRepository
) : ViewModel() {

    private val _users = MutableStateFlow<List<User>>(emptyList())
    val users: StateFlow<List<User>> = _users.asStateFlow()

    private val _loading = MutableStateFlow(false)
    val loading: StateFlow<Boolean> = _loading.asStateFlow()

    init {
        loadUsers()
    }

    fun loadUsers() {
        viewModelScope.launch {
            _loading.value = true
            _users.value = repository.getUsers()
            _loading.value = false
        }
    }
}

// VIEW (Compose)
@Composable
fun UserScreen(viewModel: UserViewModel = hiltViewModel()) {
    val users by viewModel.users.collectAsStateWithLifecycle()
    val loading by viewModel.loading.collectAsStateWithLifecycle()

    if (loading) {
        CircularProgressIndicator()
    } else {
        LazyColumn {
            items(users) { user ->
                Text(user.name)
            }
        }
    }
}

Klíčové výhody MVVM

  • ViewModel přežije rotaci obrazovky (Activity zničena, ViewModel zůstává)
  • Oddělení concerns: UI logika oddělená od business logiky
  • Testovatelnost: ViewModel a Repository lze unit testovat bez Android frameworku
  • Unidirectional Data Flow: stav teče dolů (do View), události nahoru (do ViewModelu)

Jetpack Compose

Jetpack Compose je moderní deklarativní UI framework pro Android od Googlu (stable od 2021).

Compose vs tradiční XML

XML + Views (legacy)Jetpack Compose
ParadigmaImperativníDeklarativní
UI definiceXML soubory + Kotlin/Java kódPouze Kotlin (@Composable funkce)
State managementLiveData, manuální updatesReactive (recomposition)
BoilerplateHodně (findViewById, adapters)Málo
AnimaceXML animations, complexBuilt-in, jednoduché
TestováníEspresso, těžkopádnéSnadné, kompozní testy

Základy Compose

kotlin
// Composable funkce
@Composable
fun Greeting(name: String) {
    Column(
        modifier = Modifier.padding(16.dp),
        verticalArrangement = Arrangement.spacedBy(8.dp)
    ) {
        Text(
            text = "Ahoj, $name!",
            style = MaterialTheme.typography.headlineLarge
        )
        Button(onClick = { /* akce */ }) {
            Text("Klikni mě")
        }
    }
}

State v Compose

kotlin
@Composable
fun Counter() {
    // remember: zachová hodnotu napříč recomposition
    // mutableStateOf: reaktivní stav
    var count by remember { mutableStateOf(0) }

    Column {
        Text("Kliknuto: $count×")
        Button(onClick = { count++ }) {
            Text("+1")
        }
    }
}

State hoisting

Best practice: stav drž co nejvýše v hierarchii, předávej dolů:

kotlin
// Stateful (drží vlastní stav)
@Composable
fun CounterScreen() {
    var count by remember { mutableStateOf(0) }

    // Stateless komponenta dostává stav i callback
    CounterDisplay(count = count, onIncrement = { count++ })
}

// Stateless (jen zobrazuje a deleguje akce)
@Composable
fun CounterDisplay(count: Int, onIncrement: () -> Unit) {
    Button(onClick = onIncrement) {
        Text("$count")
    }
}

Coroutines a Flow (asynchronní programování)

Coroutines

Lightweight threads pro asynchronní kód v Kotlinu. Nahrazují callbacky a thread management.

kotlin
class UserViewModel : ViewModel() {
    fun loadUsers() {
        viewModelScope.launch {
            val users = repository.getUsers()  // suspend funkce
            _users.value = users
        }
    }
}

// V Repository
class UserRepository {
    suspend fun getUsers(): List<User> {
        return withContext(Dispatchers.IO) {
            api.fetchUsers()  // síťový request
        }
    }
}
PojemVýznam
suspendFunkce, která lze pauzovat a obnovit
launchSpustí coroutine "fire and forget"
async / awaitSpustí coroutine vracející hodnotu
Dispatchers.IOPool vláken pro IO operace
Dispatchers.MainHlavní (UI) vlákno
viewModelScopeCoroutine scope vázaný na lifecycle ViewModelu

Flow (reaktivní streamy)

Flow je asynchronní stream hodnot v čase. Podobné Promise, ale může vrátit víc hodnot postupně.

kotlin
class UserRepository {
    fun observeUsers(): Flow<List<User>> = flow {
        while (true) {
            emit(api.fetchUsers())
            delay(60_000)  // každou minutu
        }
    }
}

// V ViewModelu
val users: StateFlow<List<User>> = repository.observeUsers()
    .stateIn(viewModelScope, SharingStarted.Lazily, emptyList())

Typy:

  • Flow<T>: cold stream, spouští se při collect
  • StateFlow<T>: hot stream s aktuální hodnotou (jako LiveData)
  • SharedFlow<T>: hot stream pro multi-subscriber

Gradle: build systém

Gradle je build systém Androidu. Konfiguruje se v souborech build.gradle.kts (Kotlin DSL) nebo build.gradle (Groovy DSL).

Struktura projektu

MyApp/
├── settings.gradle.kts     ← seznam modulů
├── build.gradle.kts        ← root config (verze pluginů)
├── gradle.properties       ← properties
└── app/
    ├── build.gradle.kts    ← config aplikace
    ├── src/
    │   ├── main/
    │   │   ├── AndroidManifest.xml
    │   │   ├── java/com/example/myapp/  ← Kotlin kód
    │   │   └── res/                      ← drawable, strings, layouts
    │   └── test/                          ← unit testy
    └── proguard-rules.pro                 ← R8/ProGuard pravidla

Příklad app/build.gradle.kts

kotlin
plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    id("com.google.dagger.hilt.android")
}

android {
    namespace = "com.example.myapp"
    compileSdk = 34

    defaultConfig {
        applicationId = "com.example.myapp"
        minSdk = 24
        targetSdk = 34
        versionCode = 1
        versionName = "1.0"
    }

    buildFeatures {
        compose = true
    }
}

dependencies {
    implementation("androidx.core:core-ktx:1.12.0")
    implementation("androidx.compose.material3:material3:1.2.0")
    implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0")
    implementation("io.coil-kt:coil-compose:2.5.0")
}

Klíčové Jetpack knihovny

Jetpack je sada Googlem oficiálně podporovaných knihoven, které tvoří moderní Android ekosystém.

KnihovnaK čemu
ComposeModerní UI framework
ViewModelStav UI, přežívá rotaci
LiveData / StateFlowReaktivní data
RoomSQLite ORM, jednoduché DB API
RetrofitHTTP client pro REST API
NavigationNavigace mezi obrazovkami
WorkManagerSpolehlivá background práce
DataStoreNáhrada SharedPreferences (typesafe)
HiltDependency Injection
CoilNačítání obrázků

Room příklad

kotlin
@Entity
data class User(
    @PrimaryKey val id: Int,
    val name: String,
    val email: String
)

@Dao
interface UserDao {
    @Query("SELECT * FROM user")
    fun getAll(): Flow<List<User>>

    @Insert
    suspend fun insert(user: User)
}

@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

Retrofit příklad

kotlin
interface UserApi {
    @GET("users")
    suspend fun getUsers(): List<User>

    @POST("users")
    suspend fun createUser(@Body user: User): User
}

val retrofit = Retrofit.Builder()
    .baseUrl("https://api.example.com/")
    .addConverterFactory(GsonConverterFactory.create())
    .build()

val api = retrofit.create(UserApi::class.java)

WorkManager příklad

kotlin
class UploadWorker(context: Context, params: WorkerParameters) :
    CoroutineWorker(context, params) {

    override suspend fun doWork(): Result {
        return try {
            uploadFile()
            Result.success()
        } catch (e: Exception) {
            Result.retry()
        }
    }
}

// Spuštění
val request = OneTimeWorkRequestBuilder<UploadWorker>()
    .setConstraints(Constraints.Builder()
        .setRequiredNetworkType(NetworkType.UNMETERED)
        .build())
    .build()

WorkManager.getInstance(context).enqueue(request)

Rychlý tahák

PojemKlíčová fakta
AndroidLinux-based OS od Googlu, jazyk Kotlin
ArchitekturaLinux Kernel → HAL → Libraries/ART → Framework → Apps
Linux KernelProcesy, paměť, drivers, bezpečnost (UID)
HALStandardní rozhraní pro HW
ARTAndroid Runtime, nástupce Dalvik, hybrid AOT+JIT
DEXBytecode formát ART (Dalvik Executable)
SandboxKaždá aplikace = vlastní UID, izolovaná
ActivityJedna obrazovka s UI
ServiceBackground komponenta bez UI
Foreground ServiceS povinnou notifikací (od Android 8)
Broadcast ReceiverReaguje na systémové broadcasty
Content ProviderSdílí data s jinými aplikacemi přes URI
AndroidManifest.xmlPovinný config, registrace komponent + práva
Permission NormalAuto schválené při instalaci
Permission DangerousRuntime, uživatel schvaluje za běhu
IntentZpráva spouštějící komponentu nebo předávající data
Explicitní IntentZnám konkrétní cíl
Implicitní IntentSystém najde vhodnou aplikaci (chooser)
Intent FilterDeklaruje, jaké intenty komponenta zpracuje
Activity LifecycleonCreate → onStart → onResume → onPause → onStop → onDestroy
ViewModelDrží UI state, přežije rotaci
MVVMView → ViewModel → Model (Repository)
ComposeDeklarativní UI framework, @Composable funkce
rememberZachovat stav přes recompositions
mutableStateOfReaktivní stav
State hoistingStav nahoru, callbacks dolů
CoroutinesKotlin async, suspend, viewModelScope
FlowAsynchronní stream hodnot
StateFlowHot stream s aktuální hodnotou
GradleBuild systém Androidu
JetpackSada moderních knihoven od Googlu
RoomSQLite ORM
RetrofitHTTP client pro REST API
WorkManagerSpolehlivá background práce
HiltDependency injection

Tipy pro ústní zkoušku

Jak začít

"Android je open-source mobilní operační systém od Googlu postavený na Linuxovém kernelu. Architektonicky je to zásobník vrstev: Linux kernel, HAL, Android Runtime (ART) s nativními knihovnami, Application Framework a samotné aplikace. Aplikace běží v sandboxu pro bezpečnost a izolaci. Skládá se ze čtyř základních komponent: Activity, Service, Broadcast Receiver a Content Provider, které jsou registrované v Manifestu."

Co komise typicky chce slyšet

  • 5 vrstev architektury (Linux Kernel, HAL, ART, Framework, Apps)
  • ART vs Dalvik rozdíl
  • Sandbox a jeho účel (bezpečnost, izolace)
  • 4 komponenty s konkrétními příklady
  • AndroidManifest.xml jako povinný config
  • Runtime permissions (dangerous se schvalují za běhu)
  • Intent explicit vs implicit + chooser
  • Activity lifecycle v základních krocích
  • MVVM a proč ViewModel přežije rotaci

Doplňky, které komisi potěší

  • Hybrid AOT+JIT v moderním ART
  • AOSP a custom ROMy (LineageOS, GrapheneOS)
  • Background restrictions od Android 8 (Foreground Service místo Background)
  • Compose vs XML (deklarativní vs imperativní)
  • State hoisting v Compose
  • Coroutines a Flow pro async
  • Hilt pro DI
  • WorkManager pro deferred background work
  • Single Activity Architecture jako moderní trend

Časté chytáky

OtázkaOdpověď
Rozdíl ART vs Dalvik?Dalvik byl JIT (kompilace za běhu). ART je hybrid AOT+JIT: kompiluje při instalaci a profile-guided při nečinnosti.
Co se stane při rotaci telefonu?Activity se zničí a znovu vytvoří (onDestroy → onCreate). ViewModel přežije, proto se používá pro stav.
Rozdíl explicitního a implicitního Intentu?Explicitní zná konkrétní cílovou Activity/Service. Implicitní deklaruje záměr a systém vybere vhodnou aplikaci.
Proč Manifest?Povinný config soubor. OS bez něj neví, jaké komponenty aplikace má, jaká práva chce, jakou má hlavní Activity.
Co je Sandbox?Izolace každé aplikace přes vlastní Linux UID, vlastní proces, vlastní filesystem. App A nečte data App B.
Co je Content Provider?Komponenta, která exponuje data aplikace jiným aplikacím přes standardizované URI a CRUD rozhraní.
Proč MVVM a ne MVC?MVVM odděluje state (ViewModel) od View, ViewModel přežívá konfigurační změny (rotace).
Jak funguje Compose recomposition?Když se mění State, Compose automaticky znovu vyrenderuje komponenty, které ten state čtou.