Verslag Android GSM Je kan gsm’s en hun gebruik op delen in 2 groepen. Sommige mensen gebruiken het enkel voor te bellen en eens een sms te versturen, voor de rest hebben ze enkel nood aan een adressenboek. Maar je hebt ook mensen die met hun GSM hun dagelijks leven organiseren. Zij gebruiken hun GSM naast het bellen en smsen, ook als agenda, emails na te kijken, takenlijst, etc. Vroeger waren deze laatste enkel in gebruik bij zakenmensen. Denk hier bij aan de Blackberry’s, maar tot voor kort wordt deze “multi-tasking” ook populair bij de jongeren. Kijk hierbij naar de iPhone, een product van Apple. Waar je ook verschillende “applicaties” kan instaleren. Sommige zijn gratis, andere aangeboden op een application market. Voor de Iphone’s kan je dus zelf applicaties ontwikkelen. Maar jammer genoeg moet je voor deze developpement kit een stevige prijs betalen. Er is een mogelijkheid om een studente licencie te krijgen, maar dit vraagt veel papierwerk. Dan stel ik u graag voor aan Android. Een besturingssysteem voor gsm’s uitgebracht door de welgekende firma Google.
Wat is Android Android is open-source, de linux kernel is GPL, het Android platform is ASL (Apache Software License) Dit omdat de Apache licensie meer commercieel gericht is. Applicaties voor Android zijn geschreven in Java. Deze applicaties worden uitgevoerd door een virtuele machine die op een linux kernel draait.
Linux Kernel
(Android system architecture, Bron: Google) Met de Linux Kernel kom je als gebruiker niet direct mee in contact. Deze fundamenten van het systeem verzorgen het geheugengebruik, procesbeheer, bestandssysteem, netwerk, drivers, etc... . Het is een soort van abstractie laag, hierin worden de specifieke configuraties van de hardware, het toestel, bepaalt. Er kan hier ook functionaliteit aan toegevoegd worden, zonder dat het Android systeem moet worden aangepast. Elke aplicatie heeft een eigen process, een eigen PID, elk process kan een ander process niet beïnvloeden zonder de juiste permissies. Virtuele machine Boven op deze Linux kernel draait een Dalvik Virtuele Machine (Geschreven door Google). Deze werkt me de bytecodes, gegenereerd door de Java .class en .jar ‘s. Hierdoor moet het Android systeem niet zonodig aangepast worden aan een andere hardware. Java De applicaties worden geschreven in Java. Deze worden gecompileerd tot javabytecodes maar dan vertaald naar machine onafhankelijke dex code. De werking van deze laatste blijft het zelfde, maar deze laten Android toe om deze uit te voeren in hun eigen virtuele machine die vrij is van de licensie van Sun. Maar ook geoptimaliseerd om op machines met lagere reken capaciteit te kunnen werken.
Application framework Android’s application framework bevat een soort van bouwblokken die je kan gebruiken in je applicatie. Een voorbeeld hiervan is de Activity manager, deze beheert de “life cycle” van de applicaties.
Basis principes Android: Activity Lifecycle van een Activity Bij moderne besturingssystemen zijn we gewend dat we verschillende applicaties kunnen uitvoeren, en elke is zichtbaar in een appart venster. Alle programma’s worden gelijkwaardig behandeld, buiten dat 1 de focus heeft en op de voorgrond wordt weergegeven. Bij Android is dit opzicht anders. Een applicatie neemt steeds het volledige scherm ingebruik. Als er een nieuwe applicatie wordt geopend, komt dat voor het huidige te staan. Als we 1 sluiten gaan we terug naar een vorige. Dit wordt bijgehouden door de Activity Manager in een application stack. Maar deze stack kan niet eindeloos groot zijn. Het kan niet elk process voor eeuwig laten uitvoeren. Daarom zijn er prioriteiten toegekend aan processen. Zo kan Android beslissen welke processen gesloten kunnen worden en welke te essentieel zijn om te stoppen. (Een applicatie is opgebouwd uit activitys, processen bevatten deze activitys). Het proces dat de Activity bevat dat op de voorgrond staat, krijgt natuurlijk de hoogste prioriteit. Gevolgt door processen die Activitys bevatten die wel zichtbaar zijn, maar niet op de voorgrond. Daarna de processen die de andere background Activitys bevatten. En als laatste de processen die geen Activity bevatten en dus leeg zijn. Wat gebeurd er als een proces wordt verwijderd? Daarvoor leg ik even de lifecycle van een activity uit.
(Android Activity Lifecycle; bron Google) Uit het boek, Unlocking Android, Manning: onCreate() Called when the Activity is created. Setup is done here, Also provided is access to any previously stored state in the form of a Bundle. onRestart() Called if the Activity is being restarted, if it is still in the stack, rather than starting new. onStart() Called when the Activity is becoming visible on the screen to the user. onResume() Called when the Activity starts interacting with the user. (This is always called, whether starting or restarting.) onPause() Called when the Activity is pausing or reclaiming CPU and other resources. This method is where state should be saved so that when an Activity is restarted it can start from the same state it had when it quit. onStop() Called to stop the Activity and transition it to a nonvisible phase and subsequent lifecycle events. onDestroy() Called when an Activity is being completely removed from system memory. Happens either because onFinish() is directly invoked or the system decides to stop the Activity to free up resources.
(Uit het boek, Unlocking Android, Manning) Het is dus aangeraden om bij onPauze gegevens te bewaren van de applicatie. Want vanaf dan kan het het risico lopen om van de stack verwijderd te worden. En dan zouden alle gegevens kwijt zijn. Views Een activity bestaat uit 1 of meerdere views. Deze zorgen voor de grafische inhoud van een applicatie. Zo heb je TextView, een Button, of een tekstveld. De inhoud en de opbouw van deze Views kan bepaald worden in de code. Maar een meer gebruikte manier is door middel van een beschrijving in XML. (Deze XML wordt bij het compileren omgezet in een gecomprimeerd binair formaat, geoptimaliseerd voor het mobiel toestel.) Deze XML files worden bewaard in de resources map “res”. Eclipse voorziet ook een grafische management om deze onderdelen te beheren. Als of je een wysiwyg editor hebt. Hier wordt dus het grafisch aspect van de applicatie bepaald. Zelfs de tekst inhoud, of variabelen die bepaalde kleuren bevatten worden via verwijzingen in een string.xml file bewaard. Een voorbeeld vind je later in het praktijk voorbeeld.
Android Manifest Een laatste onderdeel van een activity dat ik hier behandel. Graag verwijs ik eerst even naar de structuur van een Cocoon project. Waarmee we werkte in GWEBA. Men had daar een sitemap file. Die beetje de structuur van het systeem beschrijven. De mogelijke gebruikte paginas of functies die een gebruiker zou kunnen aanroepen worden daar beschreven. Samen met enkele permissies of het bijvoorbeeld internet of external is. Hier zie ik een lichte analogie in naar de AndroidManifestfile.
Dit bestand ( ook weer opgebouwd in een XML structuur) bevindt zich in de root van de applicatie. Het bevat alle activititys. Als er een activity opgeroepen wordt die niet in de Manifestfile staat, zal dit een kritische fout geven. Elke activity krijgt ook permissies toegewezen. Als het bijvoorbeeld connectie mag maken met het internet, een sms mag verzenden, of toegang krijgen tot het addressenboek etc. Tot zover activitys.
Basisprincipes Android: Intents en Services Een intent is een beschrijving van een actie die een gebruiker wilt uitvoeren. Zoals bel naar dit, sms naar dat, lees dit in. Dus een actie en een doel. Deze abstractie zorgt ervoor dat een andere applicatie dit “hoort” en dit voor u afhandeld. Welk applicatie dit is, kan veranderd worden via de intentfilter. Zo kan u hiervoor ook uw eigen applicatie schrijven. Een service is een soort van deamon wat op de achtergrond draait. Deze blijft uitgevoerd worden ook al wordt er tussen applicaties gewisseld. Bijvoorbeeld een mp3speler wilt dat de muziek op de achtergrond door blijft spelen. Of een gps tracking programmatje.
Praktijk voorbeeld Het begin scherm van een applicatie bevat 2 knoppen die de keuze aan de gebruiker vragen wat zijn intentie is. public class koekjes3 extends Activity implements OnClickListener{ /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); View getonlinekoekjes_knop = findViewById(R.id.knop1); getonlinekoekjes_knop.setOnClickListener(this); View nieuwonlinekoekje_knop = findViewById(R.id.knop2); nieuwonlinekoekje_knop.setOnClickListener(this);
}
} public void onClick(View v) { switch (v.getId()) { case R.id.knop1: Intent i1 = new Intent(this, ParsingXML.class); startActivity(i1); break; case R.id.knop2: Intent i2 = new Intent(this, NieuwOnlineKoekje.class); startActivity(i2); break; } }
De eerste functie die opgeroepen wordt is onCreate().
Deze haalt de layout uit R.layout.main . Er is dus een R.java bestand dat dit bevat. Maar let op, als we dit uiterlijk willen veranderen gaan we niet dit java bestand aanpassen. Want R.java wordt bij het compileren autmatisch gegenereerd uit de files in “res”. In “res” vinden we de map “main.xml” wat overeenkomt met de verwijzing R.layout.main. Main.xml ziet er als volgend uit:
<Button android:text="@string/knop1" android:id="@+id/knop1" android:layout_width="wrap_content" android:layout_height="wrap_content"> <Button android:text="@string/knop2" android:id="@+id/knop2" android:layout_width="wrap_content" android:layout_height="wrap_content">
LinearLayout betekend dat deze elementen gewoon onder elkaar worden weergegeven. Voor andere mogelijkheden verwijs ik graag naar http://developer.android.com/guide/tutorials/views/index.ht ml . Merk de Button op, deze heeft 2 attributen: text en id. De waarde van deze worden bepaald door respectivelijk @string en @+id . De eerste verwijst naar een XML file: string.xml ( <string name="knop1">). Het tweede is eigenlijk averegs. Hiermee wordt een nieuw id aangemaakt in de lijst van id’s, namelijk de naam achter ‘/’. De ContentView is nu bepaald en het bevat verschillende views. Nu gaan we functionaliteit aan deze elementen koppelen. Deze elementen kunnen we terug vinden via de ID’s. Bijvoorbeeld: View getonlinekoekjes_knop = findViewById(R.id.knop1);
We hebben nu een view in onze code aangemaakt die overeenkomt met de view gedeclareerd in de main.xml. Willen we nu een functionaliteit toevoegen dan doen we dit door gebruik te maken van bepaalde functies die dit view object bevat. Bijvoorbeeld klikken: getonlinekoekjes_knop.setOnClickListener(this);
Om deze OnClickListener aan te passen moeten we implements OnClickListener toevoegen. We overschrijven dan de functie met onze eigen OnClick. We geven bij deze functie ook de huidige view mee. Zodat men kan terug verwijzen.
Intent i1 = new Intent(this, ParsingXML.class); startActivity(i1);
Hier mee maken we een nieuwe intent aan, en we starten deze als een activity. ParsingXML is een nieuwe klasse die in de src package staat, gebaseerd op een activity. Met ook een onCreate functie. Maar hierin gaan we XML functies gebruiken. Als extra Application Framework heb ik dus een XML toepassing gemaakt. Ik maak gebruik van de API “SAXParserFactory”. Andere API’s waren ook mogelijk. Vanaf hier heb ik ook al geïllustreerd in de les. We gaan dus connectie maken met een bepaalde URL, hiervan gaan we de XML inlezen, en af handelen met een eigen XMLHandler. Deze gaan we omzetten in objecten. Welke een toString() methode bevatten waarmee we deze in de TextView weergeven. Omdat dit het schermgrootte ver overschrijdt heb ik eerst een ScrollView gemaakt die deze TextView bevat. Opmerking: in deze activity heb ik geen XML declaratie voor de views gebruikt. Maar de Views via code aangemaakt. Ook heb ik een Formulier gemaakt om nieuwe elementen aan te maken. Hier heb ik wel een XML voor de layout aangemaakt. Deze vind je terug in “res/layout/”. Daarstaan enkele TextView’s en EditText, deze laatste is een inputveld. Op het laatste een knop waarde gebruiker kan op klikken als hij het wilt verzenden. In de OnCreate() functie wordt opnieuw de XML ingelezen en weergegeven, en een onClickListener aan de knop gekoppeld. Deze OnClickListener kan dan de postData() functie oproepen. Deze verzamelt de informatie in de EditText views’s en verzend deze via HttpPost en HttpResponse API’s naarde server. Waar bijvoorbeeld een Cocoon applicatie deze gegevens verwerkt en daarna een geupdate XML file kan weergeven.
Emulator en debugger Om je applicaties uit te testen ben je natuurlijk niet verplicht om een toestel aan tekomen met een Android systeem op. Maar Android voorziet daarvoor een Emulator (AVD, Android Virtual Device). Het is eigenlijk een virtueel mobiel toestel. De eclipste extensies bevatten een leuke manier om te debuggen. (Om Android Applicaties te ontwikkelen via Eclipse, verwijs ik graag naar de appendix A: “Installing the Android SDK” uit het boek “Unlocking Android, Manning” ). Men kan in de code breakpoints toevoegen, en de applicatie laten runnen op de AVD. De debugger koppelt zich automatisch met het debugger systeem op de Android. Als het programma aan een bepaalde breakpoint is toegekomen kan je de huidige variabelen en hun inhoud bekijken. Wat zeer handig is om te debuggen. Om te eindigen zou ik graag dit schema geven wat nog eens de layers van een android systeem in kaart stelt adhv een voorbeeld over Bluethoot.