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!