Ha megérinti a „Telepítés” gombot egy APK-fájlon, vagy letölt egy alkalmazást a Play Áruházból, egy összetett műveletsor kezdődik a színfalak mögött. Az egyszerű folyamatjelző sáv valójában több tucat lépést jelent, beleértve a csomagelemzést, a kriptográfiai ellenőrzést, az engedélykezelést, a fájlkibontást és a kódoptimalizálást. Ennek a folyamatnak a megértése segít megmagyarázni, hogy a telepítések néha miért sikertelenek, és mit tehet ez ellen.
Ebben a cikkben végigjárjuk az Android telepítési folyamatának minden fontos lépését, attól a pillanattól kezdve, hogy a rendszer megkapja az APK-t, egészen addig a pontig, ahol az alkalmazás készen áll az indulásra.
1. lépés: A telepítés elindítása
A telepítési folyamat a forrástól függően eltérően kezdődik:
- Play Áruház: A Play Áruház alkalmazás letölti az APK-t (vagy felosztott APK-kat), és meghívja a rendszer csomagtelepítőjét olyan speciális jogosultságokkal, amelyek megkerülnek bizonyos felhasználói megerősítéseket.
- Oldalbetöltés: Amikor megnyit egy APK-fájlt, az Android elindítja a csomagtelepítő tevékenységet. Android 8.0 és újabb verziók esetén a telepítő alkalmazásnak rendelkeznie kell az „Ismeretlen alkalmazások telepítése” engedéllyel az adott forráshoz.
- ADB: A adb install parancs közvetlenül kommunikál a csomagkezelő szolgáltatással USB-n keresztül, teljesen megkerülve a grafikus telepítőt.
A forrástól függetlenül minden telepítés végül ugyanazt a rendszerszolgáltatást éri el: a PackageManagerService-t (PMS). Ez a központi hatóság az összes csomagművelethez Androidon.
2. lépés: Csomagelemzés
Minden más előtt a rendszernek meg kell értenie, hogy mit fog telepíteni. A PackageManagerService meghívja a PackageParser-t az APK-fájl olvasásához és metaadatainak kibontásához.
Az elemző beolvassa a AndroidManifest.xml fájlt az APK-ból. Ez a bináris XML-fájl kritikus információkat tartalmaz:
- Csomag neve: Az alkalmazás egyedi azonosítója (pl). com.example.myapp
- Verziókód és név: Annak meghatározására szolgál, hogy ez egy frissítés vagy egy friss telepítés
- Minimális és cél SDK-verziók: Meghatározza a kompatibilitást az eszközzel
- Deklarált engedélyek: Az alkalmazás által kért engedélyek és az általa meghatározott egyéni engedélyek egyaránt
- Alkatrészek: Tevékenységek, szolgáltatások, műsorszóró vevők és tartalomszolgáltatók, amelyeket az alkalmazás regisztrál
- Hardver és szoftver jellemzők: Olyan követelmények, mint a kamera, a GPS vagy bizonyos OpenGL-verziók
Ha a jegyzék hibás, vagy az APK-struktúra érvénytelen, a telepítés ebben a szakaszban meghiúsul, és „Elemzési hiba” üzenet jelenik meg. Ez az egyik leggyakoribb ok, amiért az oldalt betöltött APK-k telepítése sikertelen.
3. lépés: Kompatibilitási ellenőrzések
A jegyzék elemzése után a rendszer kompatibilitási ellenőrzések sorozatát hajtja végre:
- SDK verzió: Ha az alkalmazás minSdkVersion értéke magasabb, mint az eszköz API-szintje, a telepítés elutasításra kerül.
- ABI kompatibilitás: Ha az APK natív könyvtárakat tartalmaz, a rendszer ellenőrzi, hogy azok megfelelnek-e az eszköz CPU architektúrájának. A csak armeabi-v7a könyvtárakat tartalmazó APK nem telepíthető csak x86-os eszközre.
- Szükséges funkciók: Ha az alkalmazás deklarálja a szükséges hardverfunkciókat (például a android.hardware.telephony), a rendszer ellenőrzi, hogy az eszköz támogatja-e azokat.
- Rendelkezésre álló tárhely: A rendszer ellenőrzi, hogy van-e elég szabad hely az alkalmazás telepítéséhez, beleértve a kibontott natív könyvtárak és az optimalizált DEX-fájlok számára.
4. lépés: Aláírás ellenőrzése
Ez a telepítési folyamat egyik legkritikusabb lépése. Az Android ellenőrzi az APK kriptográfiai aláírását, hogy biztosítsa annak integritását és hitelességét.
Az ellenőrzési folyamat attól függ, hogy mely aláírási sémák vannak jelen:
V1 aláírás (JAR aláírás)
A rendszer ellenőrzi, hogy a META-INF/ könyvtárban vannak-e aláírási fájlok (.SF, .RSA vagy .DSA). Az APK-ban lévő minden egyes fájl a jegyzékben felsorolt kivonatok alapján ellenőrzött. Ez lassú, mert minden fájlt külön kell kivonatolni.
V2 aláírás (APK Signature Scheme v2)
Az Android 7.0-ban bevezetett séma a teljes APK-t bináris blobként írja alá. Az aláírási blokk a ZIP központi könyvtár és a központi könyvtár végének rekord közé kerül beillesztésre. Az ellenőrzés sokkal gyorsabb, mert a nyers bájtokon működik anélkül, hogy az egyes bejegyzéseket ki kellene tömöríteni.
V3 aláírás (kulcsforgatás)
Az Android 9.0-tól elérhető V3 séma a kulcsforgatás támogatásával egészíti ki a V2-t. Tartalmaz egy kulcsforgatást igazoló adatszerkezetet, amely összekapcsolja a régi és az új aláíró kulcsot, így a fejlesztők a frissítési kompatibilitás elvesztése nélkül cserélhetnek aláíró kulcsot.
V4 aláírás (növekményes)
Az Android 11 bevezette a V4-et a fokozatos telepítésekhez. Merkle-fa alapú aláírást biztosít, amely lehetővé teszi az egyes blokkok ellenőrzését, amint azok az eszközre streamelve kerülnek.
Ha az aláírás-ellenőrzés bármilyen okból meghiúsul, a telepítés azonnal megszakad. Telepítés előtt ellenőrizheti az APK aláírását a APK-ellenőrző eszköz segítségével.
Aláírásegyeztetés frissítése
Ha már telepítve van egy azonos csomagnevű alkalmazás, a rendszer további ellenőrzést végez: az új APK aláíró tanúsítványának meg kell egyeznie a meglévő telepítés tanúsítványával. Ez megakadályozza, hogy rosszindulatú felek manipulált verzióra cseréljenek egy eredeti alkalmazást. Ha az aláírások nem egyeznek, az „Alkalmazás nincs telepítve: A csomag ütközik egy azonos nevű meglévő csomaggal” hibaüzenet jelenik meg.
5. lépés: Felhasználói megerősítés
Oldalról betöltött telepítések esetén a rendszer megjelenít egy telepítést megerősítő párbeszédpanelt, amely a következőket mutatja:
- Az alkalmazás neve és ikonja (az APK forrásaiból kinyerve)
- Az alkalmazás által kért engedélyek (régebbi Android-verziókon)
- Legyen szó új telepítésről vagy frissítésről
- Bármilyen figyelmeztetés az alkalmazás forrásával vagy a lehetséges kockázatokkal kapcsolatban
Android 12 és újabb rendszereken a megerősítő képernyő egyszerűbb, mivel a futásidejű engedélyek egyedileg kerülnek megadásra, amikor az alkalmazásnak először szüksége van rájuk, nem pedig a telepítéskor.
6. lépés: Fájl kibontása és elhelyezése
Amint a felhasználó megerősíti (vagy a Play Áruház telepítése esetén automatikusan), a rendszer megkezdi a fájlok kicsomagolását és elhelyezését:
APK-tárhely
Maga az APK-fájl a /data/app/[package-name]-[random]/base.apk útvonalra kerül átmásolásra. Osztott APK-telepítések esetén a további fájlok – például a split_config.arm64_v8a.apk – az alap APK mellé kerülnek. A Letöltések mappában lévő eredeti APK-fájl nem módosul és nem törlődik.
Natív könyvtári kivonat
Ha az APK natív könyvtárakat tartalmaz (a lib/ mappában), a rendszer kibontja azokat a /data/app/[package-name]-[random]/lib/[abi]/ könyvtárba. Az újabb Android-verziókban az alkalmazások az android:extractNativeLibs="false" beállítással közvetlenül az APK-ból is betölthetik a natív könyvtárakat kicsomagolás nélkül, amivel tárhelyet takarítanak meg.
Adatkönyvtár létrehozása
A rendszer létrehozza az alkalmazás privát adatkönyvtárát a /data/data/[package-name]/ (vagy többfelhasználós eszközökön a /data/user/0/[package-name]/ címen). Ez a könyvtár az alkalmazáshoz rendelt egyedi Linux UID tulajdonában van, így egyetlen más alkalmazás sem érheti el root jogosultságok nélkül.
7. lépés: DEX optimalizálás
Ebben a lépésben az Android átalakítja az alkalmazás bájtkódját az eszköz specifikus hardverére optimalizált formátumba. A folyamat jelentősen fejlődött az Android története során:
The Dalvik Era (Android 4.4 és korábbi)
Az eredeti Dalvik virtuális gép Just-In-Time (JIT) összeállítást használt. A telepítés során a classes.dex fájlt ODEX fájllá optimalizálták, amely ellenőrzött és optimalizált bájtkódot tartalmazott. Ez viszonylag gyors volt, de azt jelentette, hogy az alkalmazás lassabban futott futás közben, mivel a legtöbb kódot továbbra is értelmezték.
ART AOT-val (Android 5.0–6.0)
Az Android Runtime (ART) felváltotta a Dalvik futtatókörnyezetet, és bevezette az előzetes (Ahead-Of-Time, AOT) fordítást. A telepítés során a teljes DEX bájtkód natív gépi kóddá fordult le. Ez gyorsabbá tette az alkalmazások futását, viszont jelentősen megnövelte a telepítési időt és a tárhelyigényt; egyes alkalmazások telepítése több percig is eltartott.
Profilvezérelt összeállítás (Android 7.0+)
A modern Android hibrid megközelítést alkalmaz. A telepítés során csak a kritikus indítási útvonalak fordulnak le. Miközben a felhasználó használja az alkalmazást, a rendszer végrehajtási profilokat gyűjt a gyakran használt kódrészletekről. Tétlen karbantartás idején (jellemzően éjszakai töltés közben) a rendszer ezeket a gyakori útvonalakat natív kóddá fordítja, így optimális egyensúlyt teremt a telepítési sebesség, a tárhelyhasználat és a futási teljesítmény között.
A lefordított kód a /data/dalvik-cache/ könyvtárban vagy az APK mellett tárolódik .odex, .vdex és .art fájlokként. A .vdex fájl ellenőrzött DEX-kódot, az .odex fájl lefordított natív kódot, az .art fájl pedig előre inicializált memóriaképeket tartalmaz a gyorsabb indítás érdekében.
8. lépés: Engedély regisztráció
A PackageManagerService regisztrálja az alkalmazás deklarált engedélyeit és összetevőit a rendszerben:
- A Telepítési idejű engedélyek (mint a INTERNET vagy a VIBRATE automatikusan engedélyezve van, felhasználói beavatkozás nélkül).
- A Futásidejű engedélyek (mint a CAMERA vagy a LOCATION regisztrálva van, de nincs engedélyezve). Az alkalmazásnak futás közben kell kérnie őket.
- A Szándékszűrők regisztrálva van, így a rendszer tudja, hogy mely alkalmazások milyen műveleteket képesek kezelni (például URL megnyitása vagy tartalom megosztása).
- A Tartalomszolgáltatók regisztrálva van a hatóságoknál, így más alkalmazások lekérdezhetik őket.
9. lépés: Rendszerintegráció
Az utolsó lépések az alkalmazás integrálása az Android rendszerbe:
- Csomag adatbázis frissítés: A rendszer csomagadatbázisa (/data/system/packages.xml frissül az új alkalmazás információival, beleértve a hozzárendelt UID-t, az engedélyeket és az összetevők deklarációit).
- Indító értesítés: A kezdőképernyő indítója értesítést kap az új alkalmazásról, így megjelenítheti az alkalmazás ikonját.
- Adás: A rendszer PACKAGE_ADDED adást küld, lehetővé téve más alkalmazások számára, hogy reagáljanak az új telepítésre (például a biztonsági mentési alkalmazások ütemezhetik a biztonsági mentést).
- SELinux környezet: Az alkalmazás fájljai a megfelelő SELinux biztonsági környezettel vannak ellátva a cél SDK-verzió és a deklarált engedélyek alapján.
Miért nem sikerül a telepítés?
A telepítési csővezeték megértése segít a gyakori hibák diagnosztizálásában:
- "Elemzési hiba": Az APK sérült, hiányos, vagy rosszul formázott jegyzéke van. Ez gyakran előfordul hiányos letöltéseknél vagy helytelenül konvertált fájloknál.
- "Az alkalmazás nincs telepítve" (aláírási eltérés): Egy másik kulccsal aláírt APK-val próbál frissíteni egy alkalmazást. Először el kell távolítania a meglévő verziót.
- "Nincs elegendő tárhely": Nincs elég hely az APK-hoz, a kibontott könyvtárakhoz és a DEX-optimalizálási kimenethez. A tényleges helyigény általában az APK méretének 2-3-szorosa.
- "A csomag ütközik a meglévő csomaggal": Ugyanaz a csomagnév, de más az aláírás. Gyakori a Play Áruház és az oldalról letöltött verziók közötti váltáskor.
- A verzió leminősítése letiltva: Alapértelmezés szerint az Android megakadályozza a régebbi verzió telepítését egy újabbra. Az ADB felülírhatja ezt a adb install -d-vel.
Osztott APK telepítése
Az osztott APK-k telepítésekor (az App Bundle csomagokból) a folyamat kissé eltér. A rendszer munkamenet alapú telepítés API-t használ:
- Új telepítési munkamenet jön létre
- Minden felosztott APK-fájl a munkamenetbe kerül
- A munkamenet véglegesítésre került, ami elindítja a teljes ellenőrzési folyamatot
- Minden felosztásnak egyező csomagnevekkel, verziókódokkal és aláíró tanúsítványokkal kell rendelkeznie
Ezt a mechanizmust használják az XAPK telepítői és az olyan eszközök, mint a APKS-APK egyesülés a többfájlos telepítések kezelésére.
Telepítés ADB-n keresztül
Amikor az adb install parancsot használja, a folyamat megkerüli a grafikus telepítőfelületet, de ugyanazt a belső feldolgozási láncot követi. Az ADB socket-kapcsolaton keresztül kommunikál a csomagkezelő szolgáltatással, és olyan további kapcsolókat is támogat, amelyek a grafikus felületen nem érhetők el:
- -r: A meglévő alkalmazás cseréje (újratelepítés engedélyezése)
- -d: Verzió visszaminősítésének engedélyezése
- -g: Azonnal biztosítson minden futásidejű engedélyt
- -t: Csak teszt APK-k telepítésének engedélyezése
- --install-multiple: Az osztott APK-k telepítése egyetlen munkamenetben
Mi történik az eltávolítás során
A teljesség kedvéért íme, mi történik egy alkalmazás eltávolításakor:
- Az alkalmazás folyamatai leállnak
- Az APK és a kibontott könyvtárak törlődnek a /data/app/ fájlból
- Az alkalmazás privát adatkönyvtárát eltávolítjuk (kivéve, ha a felhasználó az adatok megtartását választotta)
- A lefordított DEX gyorsítótár fájlok törlődnek
- A csomag adatbázis frissül
- A rendszer egy PACKAGE_REMOVED adást küld
- Az indító eltávolítja az alkalmazás ikonját
Vegye figyelembe, hogy a külső tárolón lévő alkalmazásspecifikus fájlok (/Android/data/[package]/ és /Android/obb/[package]/ az Android 10 és újabb rendszereken is törlődnek, köszönhetően a hatókörű tárolási kényszernek).
Miért takarít meg hibakeresési időt a PackageManager megértése?
Az Android telepítési folyamata biztonsági ellenőrzések, fájlműveletek és rendszerintegrációs lépések gondosan összehangolt sorozata. Minden lépés meghatározott célt szolgál, a manipulált alkalmazások elleni védelemtől kezdve az adott hardverre történő teljesítményoptimalizálásig. Ha a telepítés meghiúsul, a hibaüzenet általában a folyamat egy konkrét lépésére utal, így a működés ismerete segít a problémák gyors diagnosztizálásában és elhárításában.
A Play Áruházból történő telepítés, az APK kézzel történő oldalbetöltése és az ADB-vel való összeállítás ugyanazon a csatornán keresztül, amely biztosítja, hogy az eszközön lévő összes alkalmazást ellenőrizték, megfelelően helyezték el és optimalizálták a hardverhez.