A C ++ kód használatának megkezdése az Android projektben

Tavaly előadást tartottam a törökországi Ankarában, a GDG DevFest rendezvényen. Azóta is tervezem itt megosztani ezt a beszélgetést. Most, hogy PhD-jelölt vagyok és van még egy kis időm, ide teszem a posztot.

Ha szeretné megszerezni az előadást, az elérhető az én meghajtómon.

Bemelegítés

Először szeretném elmagyarázni egy alkalmazás elkészítési folyamatát az Android rendszerben. Mivel tudnia kell néhány alapvető belső dolgot, ez a téma kissé technikai jellegű.

Nem kell mindent tudnia a fenti képen - de ez jó referencia.

Most mondd, hogy Java-ra írsz egy alkalmazást Android-ra. Meglesz:

  • az alkalmazás forráskódja
  • valamilyen erőforrás fájlok (például képek vagy xml fájlok a GUI elrendezéséhez)
  • és talán néhány AIDL fájl, amelyek Java interfészek, amelyek a folyamatokat egymással beszélgetésre késztetik.

Valószínűleg további könyvtárakat és a hozzájuk kapcsolódó fájlokat is használni fog a projektjében.

Működő alkalmazás létrehozásakor először össze kell állítani ezeket a forráskódokat. A fordító egy DEX fájlt hoz létre, amelyet aztán egy virtuális gép el tud olvasni. Ezt a géppel olvasható fájlt és néhány további információt az alkalmazásról csomagkezelő csomagol össze. Az utolsó csomag - az úgynevezett APK-csomag - az utolsó alkalmazás.

Ez egy Android csomag építési folyamata a legegyszerűbben.

Android futási idő

Most beszéljünk a futási időről. Van alkalmazásod, és amikor elindul, azt egy gép olvassa. Az Android kétféle virtuális géppel rendelkezik egy alkalmazás futtatásához. Nem ismertetem a régit, Dalvik néven, mivel manapság a legtöbb Android-eszköz egy Android Run Time, ART nevű virtuális gépet futtat - tehát erről itt fogunk beszélni.

Az ART egy idő előtti (AOT) virtuális gép. Szóval, mit jelent ez? Hadd magyarázzam. Amikor az alkalmazás elindul először, a kódot gépi kódra fordítják, amelyet aztán a valós gép elolvashat. Ez azt jelenti, hogy a kód futás közben nem kerül összeállításra részenként. Ez megnöveli az alkalmazás telepítési idejét, miközben csökkenti az akkumulátor használatát.

Összegezve: írsz egy alkalmazást, majd lefordítod bináris kódra, amelyet az ART olvas. Ezután az ART átalakítja ezt a kódot natív kódgá, amelyet maga az eszköz olvashat.

ART & C ++

Mi van, ha Android alkalmazást ír Java segítségével, de van néhány C ++ kód, amely kapcsolatban áll a Java-val? Mi a hatása annak a C ++ kódnak az alkalmazás építési folyamatára vagy futási idejére? Nem túl sok.

A C ++ kódot fordítója fordítja közvetlenül a valós gépi kódra. Tehát, ha C ++ kódot használ, azt géppel olvasható kódként csomagolja a csomagjába. Az ART nem dolgozza fel újra, miközben az ART-ban olvasható kódot az első használatkor géppel olvashatóvá alakítja. Nem kell aggódnia emiatt a folyamat miatt. Csak Ön felelős egy olyan felület megírásáért, amely lehetővé teszi a Java számára, hogy beszéljen a C ++ - val. Hamarosan erről fogunk beszélni.

C ++ Build folyamat

Most beszélnünk kell a C ++ build folyamatáról. A forráskódot (a .cpp és .h fájlokat) az első processzor kibővített forráskóddá alakítja. Ez a forráskód sok kódot tartalmaz. Míg a végső futtatható fájlt a fentihez hasonló paranccsal szerezheti be, kivághatja az összeépítési lépéseket kapcsolódó jelzőkkel. A kiterjesztett forrást úgy kaphatja meg, hogy az -E jelzőt megadja a g ++ fordítónak. Van egy 40867 soros fájlom egy 4 soros "hello world" .cpp forráskódhoz.

Használja a g ++ -E hello.cpp -o hello.ii fájlt a kiterjesztett forráskód megszerzéséhez.

A második a tényleges összeállítási lépés. A fordító összeállítja kódunkat, hogy megszerezzen egy assembler fájlt. Tehát a valós fordítás egy assembler fájlt hoz létre, nem a futtatható fájlt. Ezt a fájlt egy összeállító állítja össze. A kapott kódot objektumkódnak hívjuk. Ha több könyvtárunk van egymással összekapcsolva, sok objektumkóddal rendelkezünk. Ezeket az objektumkódokat egy linker kapcsolja össze. Aztán kapunk egy futtatható fájlt.

Kétféle összekapcsolás létezik: dinamikus és statikus.

Tehát itt az ideje, hogy egy kicsit elmélyüljünk, amikor a tiszta C ++ dolgokról beszélgetünk.

A fontos dolog: A statikusan összekapcsolt könyvtárakat a kód részének tekintheti. Ezért legyen óvatos, amikor egy könyvtárat kapcsol a projektjéhez. Mivel az Ön által használt könyvtár nem biztos, hogy rendelkezik megfelelő licenccel a statikus összekapcsoláshoz. A legtöbb nyílt forráskódú könyvtár korlátozottan használható dinamikusan összekapcsoltként.

Technikai szempontból egy statikusan összekapcsolt könyvtárat a fordító összeállít a projekthez építéskor. Másrészt egy dinamikusan összekapcsolt könyvtárat az operációs rendszer futási időben kapcsol össze. Tehát nem kell terjesztenie a projektet a használt könyvtár kóddal. Használhat másik projekt könyvtárát vagy rendszerkönyvtárát is.

Emiatt a dinamikus összekapcsolás sebezhetőséget okozhat a projektben. Bár a biztonsági eset nem tartozik e bejegyzés körébe, azonban.

Néhány fogalom

CMake és Gradle

Ha C ++ kódot akarunk hozzáadni az Android projektünkhöz, akkor jó, ha a CMake-t használjuk az építési műveletek kezelésére. Emlékszel a fentebb bemutatott építési folyamatra? Ha van egy csomó C ++ könyvtár és forráskód, bonyolultabbá válik mindegyikük kezelése. A CMake-hez hasonló eszköz megkönnyíti az összeállítási folyamat végrehajtását.

A CMake alapértelmezés szerint akkor lesz elérhető, ha úgy dönt, hogy a projekt kezdetekor C ++ támogatást vesz fel. Szüksége van egy Gradle lezárásra is, hogy könyvtárakat csomagoljon az APK-ba.

ABI

Mint tudják, az Androidot számos eszközre terjesztik. Lehetséges, hogy minden eszköznek más a processzor architektúrája. C ++ kódot tartalmazó Android-alkalmazás kifejlesztésekor gondot kell fordítania azokra a platformokra, amelyeken az alkalmazás futni fog.

Emlékszel a fent bemutatott C ++ build mechanizmusra? A C ++ kódot könyvtárként kell összeállítani minden megcélzott platformhoz. Összeállíthatja a könyvtárat az összes támogatott platformra, vagy választhatja, hogy csak egy platformra fordítja.

Kérjük, vegye figyelembe, hogy a 64 bites ABI támogatás kötelező lesz az Android Pie kiadásakor, ha alkalmazását a Google Play Áruházba szeretné helyezni.

JNI

Ez az utolsó dolog, amellyel szeretnék megismertetni az Android C ++ használatával kapcsolatban. Mint korábban említettem, bemutatom ezeket a koncepciókat, figyelembe véve, hogy egy alkalmazást szeretne fejleszteni a Java segítségével.

A JNI a Java Native Interface rövidítése. Lehetővé teszi a C ++ és a Java részek számára, hogy a legegyszerűbben beszéljenek egymással. Például, ha egy függvényt szeretne meghívni a Java C ++ - jából, írjon erre a célra egy JNI felületet.

A native-lib.cpp az a felület, amely összeköti a C ++ kódot a Java kóddal. A fenti példában az egyetlen C ++ kód maga a JNI. Felveheti azonban a használni kívánt könyvtárakat, és megvalósíthat egy olyan funkciót, amely meghívja őket. Ez az új függvény meghívható a Java részből. Tehát hídként működik így.

Teendők arra az esetre, ha ki szeretnéd próbálni

Itt minden szükséges és alapvető ismerete megvan ahhoz, hogy a C ++ programot Android projektjében használja. Ha ki akarja próbálni, akkor létrehozhat egy egyszerű Android projektet C ++ kóddal.

Az alábbi képek bemutatják az ilyen projekt elindításának lépéseit. Miután befejezte őket, érdemes elolvasnia ezt a bejegyzést, hogy mélyebben módosítsa és megértse a mechanizmust.

Ez a bejegyzés csak bevezetés volt. Ne felejtsd el, hogy még sok mindent meg kell tanulni. Célom volt azonban, hogy bemutassam a legfontosabb dolgokat a C ++ használatának koncepciójával kapcsolatban.