In questa puntata vedremo come integrare gli strumenti fin qui visti in un unico tool per facilitare la gestione dei nostri progetti. In questo modo non sarà più necessario passare tra tre o quattro programmi aperti per compilare e provare le nostre applicazioni, basterà semplicemente utilizzare Eclipse.
Grazie a questo IDE potremo concentrare i nostri sforzi sulla produzione del codice e sui vari aspetti delle applicazioni che stiamo creando, con la sicurezza di avere alle spalle un tool che ci permette di compilare in modo veloce ed intuitivo.
Come avete già visto nel precedente articolo, i tool per android (sia SDK che NDK) devono essere ben configurati per funzionare correttamente ed Eclipse non è da meno. Per procedere spediti e senza intoppi è necessario configurare questo strumento perché rispetti le nostre esigenze e non sia di intralcio.
Prima di iniziare la configurazione di un nuovo progetto per Eclipse (versione da me utilizzata 3.7.2 Indigo), controllate di aver installato il plugin per Android, CDT e un plugin di nome Sequoya.
Eclipse
Aprite Eclipse e create un nuovo progetto per Android chiamandolo per esempio FirstProject, selezionate il target nella pagina successiva (nel mio caso ho scelto Android 2.3.3 API 10). Scegliete un nome per il package, io ho scelto com.pack e per finire date il nome all’activity che dovete creare, per esempio FirstProjectActivity. Non create un Test Project, non ne avete bisogno.
Con questo avrete un progetto Android di base che visualizzerà un “hello world” sullo schermo. Potete testarlo nel vostro emulatore configurando una opzione di Run dall’apposito menù. La nuova configurazione che aggiungerete dovrà avere come Project il vostro progetto, dovrà lanciare l’activity di default e nel target dovrete selezionare la vostra macchina virtuale (se non ne avete una createla con AVD, da terminale “android avd”). Se non avete problemi di configurazione, quando cliccherete su Run dovreste vedere la macchina virtuale di android che si avvia per poi eseguire il vostro codice, che equivale ad una stampa a video di una stringa.
Se fin qui non avete avuto problemi, vediamo come aggiornare il nostro progetto per contenere codice nativo compilato tramite NDK.
JNI
Clicchiamo con il tasto destro sul nome del nostro progetto e creiamo una nuova cartella chiamata jni. Al suo interno creiamo un file chiamato Android.mk. Se avete installato correttamente il plugin CDT, dovreste vedere questo file con un’icona avente un cerchio verde in basso a destra, altrimenti controllate di aver installato bene ogni componente. Nel file Android.mk inseriamo le seguenti righe :
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := mylib LOCAL_SRC_FILES := com_pack_FirstProjectActivity.c include $(BUILD_SHARED_LIBRARY)
Modifichiamo la nostra activity in questo modo :
package com.pack; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class FirstProjectActivity extends Activity { public native String getMyData(); public native String getTextArea(); static { System.loadLibrary("mylib"); } /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); TextView tv = new TextView(this); tv.setText( getTextArea() ); setContentView(tv); setTitle(getMyData()); } }
Ora dobbiamo creare un file header per le funzioni native che abbiamo scritto. In questo caso ci viene in aiuto un tool esterno chiamato javah. Impostiamo quindi questo external tool per generare questo file: andate sul menù Run-> External Tool -> External tool configuration.
Configuriamo un nuovo Programma che avrà come locazione il percorso assoluto per il vostro eseguibile javah. E’ possibile trovarlo scrivendo da terminale il comando “which javah” (per gli utenti windows dovrebbe essere in una cartella equivalente a questa : C:\Java\jdk1.7.0_02\bin\javah.exe). Di seguito indicherò come settare la working directory e gli arguments:
Working Directory : ${workspace_loc:/FirstProject/bin} Arguments : -v -d ${workspace_loc:/FirstProject/jni} -classpath ${workspace_loc:/FirstProject/src} com.pack.FirstProjectActivity
Il refresh del tool dovrà avvenire solo alla modifica di una specifica risorsa, cioè la cartella jni. Indichiamo quindi opportunamente questa cosa nel tab Refresh del tool appena creato.
Una volta eseguito il tool esterno, basterà verificare che il contenuto della cartella jni e controllare che sia stato creato per noi un header file di questo tipo :
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_pack_FirstProjectActivity */ #ifndef _Included_com_pack_FirstProjectActivity #define _Included_com_pack_FirstProjectActivity #ifdef __cplusplus extern "C" { #endif /* * Class: com_pack_FirstProjectActivity * Method: getMyData * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_pack_FirstProjectActivity_getMyData (JNIEnv *, jobject); /* * Class: com_pack_FirstProjectActivity * Method: getTextArea * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_pack_FirstProjectActivity_getTextArea (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
Non ci resta che implementare le funzioni create nell’header nel file C che abbiamo già indicato in LOCAL_SRC_FILES (il nome non era un caso :D ), creandolo sempre all’interno della cartella jni il file com_pack_FirstProjectActivity.c :
#include "com_pack_FirstProjectActivity.h" JNIEXPORT jstring Java_com_pack_FirstProjectActivity_getMyData (JNIEnv* pEnv, jobject pThis) { return (*pEnv)->NewStringUTF(pEnv, "Native C "); } JNIEXPORT jstring Java_com_pack_FirstProjectActivity_getTextArea (JNIEnv* pEnv, jobject pThis) { return (*pEnv)->NewStringUTF(pEnv, "This is my text from C \n\n:D"); }
Arrivati a questo punto, se il plugin Sequoyah è installato correttamente e configurato ( controllate se in Windows->Preference->Android->Native Development è presente la directory nel vostro NDK), cliccate con il tasto destro sul nome del progetto, selezionate la voce Android tool e successivamente Add Native Support.
Fatto questo indichiamo i Paths and Symbols relativi al nostro codice nativo. Per farlo clicchiamo sempre con il tasto destro sul nostro progetto, poi su proprietà e cercate la voce prima menzionata.
Sul linguaggio Assembly aggiungiamo la seguente cartella :
Android/android-ndk-r7b/platforms/android-9/arch-arm/usr/include
E selezioniamo la spunta per tutti i linguaggi (Add to All Languages). A questo punto, se cliccate su applica, vi chiederà di ricompilare il progetto per aggiornare il tutto.
Se non vi sono errori, potete avviare la vostra applicazione nativa sull’emulatore semplicemente premendo Run. Dovreste visualizzare la seguente schermata :
Un piccolo suggerimento sulla toolchain per gli utenti windows :
- Potrebbe esere necessario specificare per intero il build command invece del semplice ndk-build; ad esempio, potrebbe essere necessario scrivere : bash C:\Android\android-ndk-r7b\ndk-build
Conclusioni
Spero di non essere andato troppo di fretta e mi scuso per i termini tra l’inglese e l’italiano utilizzati nel tutorial. Ho voluto mantenere alcune voci in lingua straniera perché più facili da reperire facendo qualche ricerca online.
Con questo possiamo far salpare la nave verso il mondo di Android, con tutti i tool a nostra disposizione tramite un semplice click!
Su Windows usare NDK è un casino. Consiglio a chi volesse cimentarsi con questo genere di progetti, di usare Linux (magari in VirtualBox) perchè l’installazione di cygwin, oltre ad impestare il PC, si porta dietro una caterva di roba Unix che mi ha sempre creato problemi sia con Android sia, in passato, con il Nintendo Nitro SDK (un kit di sviluppo ufficiale, che usavo in azienda, basato su Cygwin e di cui non esiste l’equivalente Linux).
Scusate la provocazione … ma tutto sto casino per scrivere in pratica un HelloWorld?!??!
beh, è un Hello World scritto in 2 linguaggi diversi, con interfacciamento tra codice nativo e Dalvik VM.
Quindi ci vogliono 2 progetti, 2 compilatori, una serie di plugin per l’interfacciamento delle varie parti e un wrapper lato Java per incapsulare le chiamate native (JNI).
E’ una struttura abbastanza standard per tutti quei progetti che mixano linguaggi diversi.
Interessante…
Ma non sarebbe più facile avere un abiente di sviluppo tutto integrato? Qualcosa tipo visual c, o delphi, che magari permette anche di buttare giù un interfaccia grafica…
Insomma nel 2012 penso dovrebbe essere una cosa facile, no? E permetterebbe una maggiore produzione con una maggiore diffusione di tutto il sistema…
Android è di Google e i soldi non mancano…
Ciao a tutti.
@fog76: purtroppo sviluppare su Android non è semplice come usare gli strumenti Microsoft. C’è un abisso in quanto a professionalità dei rispettivi SDK, documentazione, tools, ecc…
Capisco, Antonio, però il lavoro “maggiore” l’hanno fatto no? Insomma rilasciare un sdk è già una cosa importante. Se fossi io prenderei 5/10 programmatori e li dirotterei alla realizzazione di un ambiente integrato…
Prendi come esempio Microchip, per i suoi microcontrollers offre un ambiente molto bello… scegli il tipo di device e già puoi iniziare a scrivere codice.
Non nascondo che di Android mi ha sempre lasciato “perplesso” il suo sistema un pò macchinoso di sviluppo (ma anche un pò il suo utilizzo, in realtà. Ho avuto a che fare con terminali Alcatel con Android e devo dire che mi è sembrato un pò macchinoso).
Saluti.
Secondo la mia esperienza di sviluppo Android, mi sembra di capire che Google adori particolarmente lo spaghetti coding e la stesura di API ad muzzum.
Non è la quantità di soldi il problema, ma come vengono spesi.
Non è raro vedere nascere librerie dal nulla (spesso totalmente avulse dal resto dell’SDK) da parte di dipendenti Google annoiati, e poi vedere queste lib integrate (pardon: copia-incollate) nel ramo principale dopo 3 mesi, senza un briciolo di consistenza…
Concordo pienamente con Antonio riguardo la “filosofia” Google. :D
Per quanto riguarda l’articolo, so che sembra molto frivolo, ma data la natura complessa dei tool da utilizzare, come già avete discusso nei commenti, mi sembrava doveroso fare questi preamboli. Tanto più che non esiste un punto di riferimento vero e proprio, come già sottolineato da fog76.
Se sono cose che già sapete o troppo banali, potete tranquillamente saltarle ed aspettare articoli più interessanti… :P
ammazza che casino! mi è passata la voglia di seguire la rubrica :D ma ricorrere alla sola SDK per sviluppare un gioco su android (quindi senza l’NDK) che limiti comporta?
Io cmq finora avevo provato a installare per curiosità Necessitas per programmare sfruttando le QT (si usa sempre l’ndk) e mi è sembrato tutto molto più semplice, almeno per quanto riguarda questa prima fase di preparazione!
@zephyr83
Per sviluppare con Qt sicuramente è la strada migliore, conta però che si appoggia anche all’app Ministro, che fa il lavoro sporco per quanto riguarda l’installazione delle librerie Qt su Android.
Se si sviluppa un gioco solo per Android usare l’sdk e basta non coporta nessuna limitazione. L’NDK ti permette in più di estendere le tue app con codice scritto in C/C++ che magari hai utilizzato per altri progetti o su altre piattaforme. Per ulteriori informazioni consulta questa pagina :
http://developer.android.com/sdk/ndk/overview.html
Il mio intento non era certo quello di offrire un tool veloce da utilizzare o limitato, ma quello di mettervi in condizioni di crearvi il vostro ambiente di lavoro personalizzato e versatile.
@Mirco Tracolli
La mia è solo curiosità, so a cosa serve l’NDK ma mi piacerebbe sapere se per caso l’utilizzo della sola SDK porta a qualche limitazione e se in teoria si possono realizzare le stesse applicazioni (in questo caso giochi) che si realizzano cn l’NDK. anche google stessa “sconsiglia” l’uso dell’NDK se nn strettamente necessario visto che comporta qualche complicazione in più però vedo che se ne fa largo uso sia nei giochi che nelle applicazioni multimediali (vedi lettori video). Per esempio realizzare un codec usando la sola SDK è fattibile ma richiederebbe più lavoro per lo sviluppatore oppure ci sn delle limitazioni che non permettono di ottenere lo stesso risultato o le stesse prestazioni?
Cmq, come già visto in altri articoli di Cesare Di Mauro, mi pare davvero incredibile che gli strumenti di sviluppo messi a disposizione da google per un progetto così diffuso e importante come Android siano a questi “livelli”.
Si potrebbe certamente fare di meglio! per curiosità ho riprovato a mettere su Necessitas, ho solo dovuto scaricare un singolo file di installazione (disponibile per windows, linux e osx) che si è occupato di tutto (pure dell’sdk, ndk ed emulatore di android oltre che agli strumenti di QT), configurare due cose in croce e ho realizzato un Hello Word in un battibaleno (e nn so programmare neanche in c++ ma era già tutto pronto)! L’unico inconveniente è stato installare Ministro II sull’emulatore che aveva solo la vecchia versione (ho dovuto prendere l’APK dal mio smartphone). Possibile che quelli di google non riescano a realizzare qualcosa di simile?
Non è incredibile. Negli anni ho imparato a conoscere un po’ della filosofia di Google. Quando deve realizzare qualcosa, attinge più che può dal mondo open source, e la getta nel mercato prima possibile, risparmiando al massimo sui costi. Con tutte le conseguenze che può portare una scelta del genere, e Android penso sia l’esempio più eloquente.
Riguardo all’NDK, da quel che ho visto da questo articolo non oso immaginare cosa succederebbe nel caso di problemi. Da sviluppatore penso che lavorarci sarebbe un incubo, a caccia del “bug maledetto che non riesco a trovare”.
Non invidio proprio chi deve averci a che fare per forza su progetti non banali.
Tra l’altro giusto in questi giorni nel gruppo Google Android su LinkedIn c’è una discussione aperta da uno sviluppatore che sta cercando di effettuare il porting su Android di un suo progetto che gira già su altre piattaforme, e si sta scontrando coi primi problemi di compilazione con l’NDK su Windows.
Google può sconsigliare quanto vuole l’uso dell’NDK, ma quando è necessario? Lo si deve usare. E qui sorgono i problemi. Infatti nonostante lo metta a disposizione anche per Windows, ci sono tutta una serie di rogne che saltano fuori a causa del pastrocchio che fornisce.
La cosa allucinante, a 2012 ormai inoltrato, è che si debba installare l’NDK “il più possibile vicino alla root del filesystem e senza spazi nel path”. Questo è il consiglio che è stato dato giusti ieri se non ricordo male.
Per me delle due l’una: o metti a disposizione uno strumento che FUNZIONA senza problemi (grossi; qualche piccolo bug è fisiologico per qualunque software, ma in linea generale il prodotto deve andare), oppure te lo tieni per te finché non è abbastanza maturo per farlo uscire.
Non è possibile che lo butti sul mercato così, lasciando gli sviluppatori a sbatterci la testa perdendo tempo prezioso (e serenità), a fare da cavie. Non è corretto. Non è professionale.
@Cesare Di Mauro
Hai perfettamente ragione, codivido in toto la tua visione delle cose.
P.s.
Non conosceno Necessitas, sembra interessante…
Saluti.
@zephyr83
Purtroppo questo è il mondo di Google, per il momento non si può fare diversamente… :D
…e mi sembra che non manchino nè gli sviluppatori nè i software di qualità ;-)
A volte il pragmatismo ripaga, pazienza se scontenta un po’ di gente :-D
BTW ultimamente sto (sotto costrizione) smanettando con Appcelerator… quello sì che è un incubo XD
@Marco
No infatti non mancano però nn è una “scusante”! Se si può fare di meglio perché non farlo? magari si vedrebbero ancora più programmi anche per qualità! Personalmente, leggendo questo e i vecchi articoli di Cesare sn rimasto allucinato!!!
@Marco: pragmatismo non significa offrire agli sviluppatori strumenti di scarsa qualità.
Che poi con questi strumenti si tirino fuori ugualmente software di qualità, mi sembra che nessuno l’abbia messo in discussione. ;)
Appcelerator Titanium si presenta molto bene, ma ha parecchie rogne, soprattutto a runtime (memory leak a tempesta).
PhoneGap si presenta meno bene (perché devi usare HTML5 + CSS + Javascript: al solo pensiero mi verrebbe da buttarmi dal balcone), ma sembra più solido.
Appena posso valuterò MonoDroid e MonoTouch, perché sinceramente vorrei uscire dall’incubo di strumenti come Titanium e PhoneGap che sono, sì, multipiattaforma ma ti costringono a compromessi o a ingoiare rospi.
La mia idea è di spostare tutta la business logic su librerie comuni in C#, e usare la GUI nativa per presentare i risultati.
In questo modo si unirebbe il vantaggio di tirare fuori applicazioni native, ma condividendo buona parte del codice.
Questo sulla carta. Vedremo nella pratica.
@Cesare @zephyr83
Vero, verissimo. Intendevo dire che “gettare nel mercato prima possibile” spesso è la scelta vincente (purtroppo) e che altrettanto spesso fa a pugni con la qualità.
Il repentino successo globale infine sta forzando un po’ tutti gli sviluppatori ad aver a che fare con android, anche quelli che, come me, normalmente se ne sarebbero tenuti ben alla larga.
@Cesare
Con Titanium sto incontrando ancora una marea di problemi, oltre all’instabilità generale di tutto l’ambiente, che minano pesantemente la produttività. Spero in future prossime release che risolvano qualcosina perché le premesse sono interessanti in effetti.
Di multipiattaforma oltre a Titanium ho provato solo Rhomobile… trattasi di un application server embedded che fa girare un MVC con business logic in Ruby e view in HTML/JQuery mobile (anche qui da buttarsi dal balcone).
Facci sapere come ti trovi con MonoDroid :-) Spero di riuscire a provarlo anch’io al più presto.
Scusami, avevo capito male allora. -_-
Pensavo di scrivere qualcosa quando avrò il tempo di smanettare soprattutto con MonoDroid (di MonoTouch so che funziona, e pure bene; ma devo essere sicuro che lo stesso sia per MonoDroid per quel che ho in mente di fare).
Credo sia interessante presentare qualcosa che vada a toccare il multipiattaforma, perché è una realtà che non si può nascondere e, soprattutto, è lo stesso mercato che ce lo chiede.
Per essere competitivi oggi la strada è praticamente obbligata, altrimenti si soccombe o si fa la fame.
Bhe per una volta stra concordo con Cesare, il multipiattaforma è la cosa migliore e non solo in ambito mobile! qui l’esigenza si sente maggiormente vista la maggior concorrenza fra le varie piattaforme.
Ragazzi, fare un’applicazione (complessa) per Android 1.6/2.x/3.x/4.x è già un complesso esercizio di sviluppo multipiattaforma!
Non oso immaginare l’incubo di un sistema basato su Javascript e HTML… tantovale evitare di sviluppare “apps” e fare siti ottimizzati bene per il mobile X_x
ciao, qualcuno ha già provato a smanettare con http://appinventor.mit.edu/? Limiti, potenzialità?
@ghipaz
Ho provato app inventor molto tempo fa, quindi non so dirti di preciso a che punto sono dello sviluppo… credo però che questo link racchiuda l’idea complessiva che puoi farti di questo tool, spero sia utile :
http://www.appinventor.org/capabilities-limitations
Scusate ma qualcuno di voi ha usato Ministro,cme ho letto, ha me comunque da un problema…a volte devo ricaricare le librerie senza aver fatto modifiche o altro, voi avete risolto?
@ Gian Piero
Purtroppo non ho mai provato Ministro, ha un sito ufficiale su cui fare riferimento?
Io l’ho provato ma per curiosità, non sn programmatore! Di certo le prime fasi illustrate in questi articoli sn molto più facili, una volta installato e configurato si può scrivere subito un “hello word”.
Il sito di riferimento è questo
http://sourceforge.net/p/necessitas/home/necessitas/
@ zephyr83
Se devi scrivere applicazioni Qt per Android, va benissimo… :D