Folosind ndk în studioul Android

În prezent, printre dezvoltatorii de Android este foarte popular mediul de dezvoltare Android Studio, pe baza IntelliJ IDEA de la JetBrains. Cu toate acestea, atunci când se utilizează IDE de acest lucru, pot apărea probleme în dezvoltarea de aplicații folosind cod nativ ca Android NDK este destinat în primul rând pentru a utiliza IDE Eclipse si ADT.







Deoarece există multe articole care descriu lucrul cu NDK, nu voi folosi bibliotecile complexe ca exemplu, ci mă voi limita la cel mai simplu exemplu de salut-juni. Codul sursă pentru acest exemplu poate fi găsit în <путь_к_ndk>/ probe / hello-jni

În mediul Eclipse, nu au existat probleme speciale cu utilizarea NDK. Catalogul de proiecte arată astfel:

Folosind ndk în studioul Android

Figura 1. Directorul principal al proiectului pentru Eclipse

Suntem interesați de directoarele jni și libs. Directorul jni conține cod sursă în limbile materne (* .c; * .cpp), fișiere antet (* .h), makefiles (* .mk). Pentru o lungă perioadă de timp nu voi vorbi despre scopul acestor dosare, fiindcă multe materiale și articole sunt dedicate acestui lucru. Voi menționa doar că jni reprezintă interfața nativă java. Este prin această interfață că procedurile native sunt chemați de la cod la java. Deci, nu uitați să conectați biblioteca în fișierele c / c ++ și amintiți-vă de sintaxa corectă a funcțiilor care vor fi chemați prin jni. De exemplu, în cazul meu, aplicația are numele pachetului:
evi.ntest
astfel încât descrierea funcției arată astfel:

în cazul în care jstring - denumirea tipului de date c, care corespunde tip șir în Java, Java - în acest caz, prefixul de serviciu care indică limba din care se numește funcția, evi_ntest - numele pachetului, care va apela funcția, MainActivity - numele activitã din care va fi numit funcția, stringFromJNI este numele funcției.
În codul java, descrierea acestei funcții pare mult mai simplă:

Nu uitați să specificați, de asemenea, fișierele de coduri utilizate în fișierele .mk. Pentru început, puteți folosi fișierele .mk din exemplele NDK, modificând numele fișierelor, dar în viitor vă recomand să le studiați structura.

Directorul libs conține biblioteci predefinite binare pentru diferite arhitecturi de procesoare (în mod implicit - armeabi). O bibliotecă dinamică este un fișier cu o extensie .so, o bibliotecă statică este un fișier cu extensia .a. Pentru a obține aceste biblioteci, trebuie să compilați sursele folosind NDK-ul Android. Pe sistemele Unix (în cazul meu - Mac OSX) pentru aceasta este necesar ca terminalul să introducă următoarele linii:

Astfel, NDK compilează automat codurile sursă de foldere JNI și plasează biblioteca obținută în libs / armeabi (de asemenea, poate fi setat în cadrul x86 de compilare parametrii liniei de comandă, MIPS, procesoare ARM V7-neon).
Când utilizați Windows, va trebui să utilizați utilitare suplimentare, eventual - plug-in-uri pentru MS Visual Studio.
În orice caz, nu contează ce fel de biblioteci obține gata, important este faptul că, în cazul în care directorul de proiect este un libs subdirector, de Eclipse în ansamblul activează automat conținutul la APK-fișier.

Mă întorc la secțiunea principală a articolului - configurarea IDE-ului Android Studio pentru a lucra cu codul nativ.

Mediul Android Studio colectează, în mod implicit, fișierul APK utilizând grală. Acest colector are o posibilitate largă de personalizare, dar la setările standard gral nu include bibliotecile native din fișierul APK.

Luați în considerare structura parțială a proiectului în Android Studio:

Fig.2 Calea către codul sursă al proiectului Android Studio.







La locul de muncă, am avut o dorință logică de a plasa un dosar JNI în directorul src / Main, din moment ce este în cazul în care sunt stocate toate celelalte fișiere sursă. Desigur, cititorul poate plasa directorul jni unde este convenabil. Principalul lucru - nu uitați să colecteze bibliotecă binar folosind NDK (din nou, pe un sistem UNIX pentru a face acest lucru în terminal du-te la directorul care conține JNI, apoi apel fișierul executabil NDK-construi, situată într-un dosar cu NDK, o cale completă pentru a-l în același terminal, în MS Windows trebuie să utilizați utilitare suplimentare). Problema este că, în mod implicit, gradația nu va fi împachetată în biblioteca APK.

Cu toate acestea, gral este ușor de configurat pentru a include în ansamblul de biblioteci java (* .jar fișiere). Trebuie menționat faptul că fișierele cu jar sunt arhive zip care conțin orice resurse, precum și codul obiect. Astfel, pentru a include bibliotecile binare * .so și * .a este suficient să le împachetați într-un fișier de jar.
Acest lucru se face astfel:

  • Redenumiți folderul libs care conține bibliotecile noastre binare în lib
  • Comprimăm acest dosar cu orice zip-archiver
  • Schimbați extensia fișierului primit în .jar

Biblioteca rezultată poate fi conectat la faza de asamblare a proiectului, cu rezultat APK-fișier va include biblioteci și aplicații binare - proceduri de apel scrise în cod nativ.
Această problemă a fost discutată de mai multe ori în diferite forumuri în limba engleză, de exemplu Stack Overflow:

Cu toate acestea, aceste informații sunt destul de scurte, fragmentate și necesită cititorului cunoștințe despre gradația sintaxei. Scopul articolului meu este de a oferi cititorilor o explicație detaliată în limba rusă, accesibilă chiar și celor care tocmai au început să lucreze cu Android Studio și grală.

Să analizăm două moduri de ambalare a bibliotecilor: manuală și automată.

Metoda manuală de ambalare:

Această metodă este foarte incomodă, dar există. Un caz admisibil de aplicare în practică: disponibilitatea unei biblioteci finalizate și nu este necesară schimbarea acesteia. În acest caz, operațiunile descrise mai jos trebuie efectuate numai o singură dată.

Acest fișier inițial arată astfel:

În partea de jos există o dependență de secțiune. Ar trebui adăugat această linie:

compilați fileTree (dir: 'src / main /', include: '* .jar')

Familiarizați-vă cu fișierul modificat de construcție, pentru a nu confunda dependențele și buildscript.dependencies.

Cititorul va fi observat, probabil, că această metodă este foarte inconfortabil în prezența necesității de schimbări frecvente în cod nativ, pentru că după ce este necesar fiecare recompilarea pentru a elimina vechi jar-fișier, redenumiți dosarul pentru libs lib, arhivați, modificați extensia de fișier. Prin urmare, folosim puterea graului și automatizăm procesul.

Generatorul de pachete de grătare vă permite să creați sarcini (funcții), precum și capacitatea sa de a crea diferite tipuri de arhive, inclusiv zip. Să folosim acest lucru și să adăugăm următoarele linii la build.gradle (locația acestui fișier este discutată mai sus):

din fileTree (dir: 'src / main / libs', include: '** / *.

Trebuie să utilizați:

din fileTree (dir: 'src / main / libs', include: '** / *. *')

Apoi, adăugați următoarea linie la secțiunea dependențe:

compilați fișierulTree (dir: "$ buildDir / native-libs", include: "native-libs.jar")

În timpul asamblării, această comandă va include conținutul bibliotecii native-libs.jar creată în fișierul APK.

Exemplu de gradație construită cu acest cod:

Dacă totul se face corect, atunci în timpul asamblării proiectului, Android Studio va crea automat biblioteca corectă în directorul de construire și îl va include în programul finit. Astfel, după fiecare recompilare a codului nativ, nu este nevoie să efectuați alte acțiuni și setări, iar gradele va face totul în sine.

Rezumat scurt
  1. Deschideți dosarul "<путь_к_проекту>/<имя_проекта>Proiect /<имя_проекта>/ src / main "și să creeze un subfolder jni acolo.
  2. Deschideți fișierul "<путь_к_проекту>/<имя_проекта>Proiect /<имя_проекта>/build.grada ", modificați secțiunea dependențe, apoi adăugați următorul cod:

Pentru a activa și bibliotecile statice * .a (dacă sunt disponibile), schimbați linia

din fileTree (dir: 'src / main / libs', include: '** / *.

din fileTree (dir: 'src / main / libs', include: '** / *. *')

  • În subfolderul jni plasăm fișierele * .mk, * .h, * .c, scriem codul nativ.
  • Deschideți dosarul "<путь_к_проекту>/<имя_проекта>Proiect /<имя_проекта>/ src / main "în terminal.
  • Introduceți terminalul în terminal <путь_к_ndk>/ ndk-build
  • Rulați proiectul.
  • Important!
    Instrucțiunea dată este destinată sistemelor de operare Unix (în cazul meu - MacOSX). Pentru sistemul de operare MS Windows, elementele 4 și 5 nu sunt relevante, deoarece sunt necesare utilitare suplimentare pentru a compila bibliotecile native. De asemenea, cel mai probabil, va fi recomandabil să schimbați modalitățile de stocare a bibliotecilor pentru cele mai convenabile și să le țineți cont în scriptul de construire.

    Cu succes pentru tine de programare nativ, principalul lucru - de fiecare dată, nu uitați să vă întrebați dacă merită să utilizați codul nativ. Ar putea exista un Java-analogi, a căror utilizare este mai ușor și, în cele mai multe cazuri - este mai bine, deoarece reduce timpul de dezvoltare, îmbunătățește alt cod inteligibilitate, reduce complexitatea arhitecturii de aplicare și puterea de dispozitive moderne este suficientă pentru cele mai multe sarcini, chiar și în Dalvik VM.







    Articole similare

    Trimiteți-le prietenilor: