A mobil eszközök sajátosságai okán az Android platformra írt alkalmazás eltérően működik, mint egy asztali operációs rendszerre írt alkalmazás. Ennek oka elsősorban a rendelkezésre álló energia szűkössége, de a kijelző kis mérete sem teszi lehetővé, hogy alkalmazásaink ablakát egymás mellé tegyük. Sok mobil platform egyszerűen oldja meg ezt a problémát: egyszerre csak egy alkalmazás futását teszik lehetővé.

2.1. Android alkalmazások

Az Android platformon is találunk bőven olyan korlátozásokat, amelyek a platform jellegéből adódnak, ne gondoljuk, hogy egy PC platformra megírt Java alkalmazás futni fog Android alatt! Ám az egyik legnagyobb korlátozás mindössze az, hogy a képernyőt mindig teljes egészében elfoglalja az alkalmazásunk, leszámítva a mobil eszköz státusz sorát, illetve az alkalmazás "ablakának" fejlécét (természetesen teljes képernyős módban ezek is elrejthetőek).

A mobil eszközök a többfeladatos működést se szokták támogatni, s ez Android esetén is trükkösen van megoldva. Egy véletlenül háttérbe taszított alkalmazás jelentősen csökkentheti a mobil eszköz rendelkezésre állását, ezért alapból a programok csak akkor futnak, ha előtérben vannak. Amint háttérbe teszünk egy alkalmazást, az operációs rendszer felfüggeszti a program futását, de a programozó által szolgáltatásként elindított szálat futni hagyja. Ezen túl a platform lehetővé teszi, hogy különféle eseményekre a program elinduljon és reagáljon az eseményre.

Nézzük az alkalmazások - szövegesen már említett - részeit az Android nyelvezetében:

2.1.1. Az Activity

Az Activity osztályok az alkalmazásaink legfontosabb részét adják: egy-egy Activity leszármazott egy-egy képernyő a mobil eszköz kijelzőjén. Egyszerre mindig csak egy Activity látható, de egy alkalmazáshoz több képernyőkép tartozhat, amelyeket futás közben - események hatására - szabadon cserélhetünk. Minden programnak kell legyen egy belépési pontja, amely az az Activity leszármazott, amelyet először mutat meg a felhasználónak.

2.1.2. Az Intent

Egy Intent feladata a külső események kezelése. Minden alkalmazás fel tud iratkozni egy-egy - akár a platform által nyújtott, akár magunk által definiált - külső eseményre, mint a bejövő hívás vagy egy időpont bekövetkezte. Le kell származtatnunk egy saját példányt a BroadcastReceiver osztályból, és meg kell mondanunk, hogy milyen eseményre figyeljen. Ezt megtehetjük az AndroidManifest.xml állományban, vagy akár a program futása közben is. Ha az alkalmazásunk nem fut, a figyelt események bekövetkeztekor a platform gondoskodik az elindításról.

2.1.3. A Service

Sok alkalmazás igényli, hogy bezárt ablakkal is képes legyen futni a háttérben, ezt szolgáltatásként megteheti, egyszerűen kell egy Service osztályból leszármazott példány, így marad a programunknak olyan része, amely a felfüggesztett Activity esetén is fut (gondoljunk például egy média lejátszóra). Minden szolgáltatást addig futtat a platform, amíg azok be nem fejeződnek, s a futó alkalmazások képesek hozzákapcsolódni a szolgáltatásokhoz, így képesek vagyunk vezérelni a háttérben futó szolgáltatást.

2.1.4. A Content Provider

Általában minden alkalmazás tárol adatokat két futás között, hiszen ha felfüggesztés helyett bezárnánk az alkalmazást, akkor elvesznének az addig összegyűjtött adatok. A platformon lehetőségünk van állományokba vagy SQLite adatbázisba menteni adatokat, és ezt segíti a Content Provider, illetve lehetővé teszi, hogy két alkalmazás adatokat cseréljen egymással.

2.1.5. Alkalmazások támogatása

Az eddig tárgyalt részek elegendőek ahhoz, hogy programjainknak legyen felülete, képesek legyenek eseményeket kezelni, illetve adatokat menteni és a háttérben futni. Szükség van ezen túl olyan osztály-könyvtárakra, amelyek támogatást adnak a hardver kezeléséhez:

2.2. A forrás szerkezete

Egy Android projekt nagyjából úgy épül fel, mint egy átlagos Java projekt, a Java osztályok a megszokott java kiterjesztésű fájlokban vannak, a megszokott csomagstruktúrában, s a megszokott módon kell fordítani ezeket a forrásfájlokat. Ha jobban körülnéztünk, akkor látunk egy AndroidManifest.xml állományt, amely a projekt lelke, itt kell leírni mindent, ami az alkalmazásunkkal kapcsolatos. A példánkban így néz ki:

<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="hu.javaforum.android">
    <application>
         <activity android:name=".HelloActivity" android:label="HelloActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>
</manifest>

A fenti példa az a minimum, amelynek minden alkalmazásban szerepelnie kell, egyszerűen definiáljuk azt az Activity osztályt, amely a programunk belépési pontja, illetve azokat a feltételeket, amelyek aktivizálják: jelen esetben nem figyelünk eseményeket, a program indítását a felhasználóra bízzuk.

A Java források mellett találunk egy (általában) res nevű könyvtárat, amely a programunkhoz csomagolt erőforrásokat tartalmazza. Ilyen erőforrások a megjelenő ikonok, illetve sok egyéb XML fájl, amelyek például leírják a grafikus felületet. Minden olyan dolgot ide kell tennünk, amely nem Java program. Az első példánkban kell legyen itt egy strings.xml a values könyvtár alatt, amelyben a használt szövegek vannak összegyűjtve:

<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <string name="app_name">HelloJavaForum</string>
</resources>

 A másik fontos XML a layout mappában lévő main.xml, amely az elrendezést hordozza:

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">"
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Hello Android"/>
</LinearLayout>

 Ezt azonban egy laza mozdulattal felülírtuk, amikor a HelloActivity nevű osztályban közvetlenül adtuk hozzá a TextView példányt az Activity területéhez, ezért erről majd a későbbiekben szót ejtünk.

Mint már tudjuk, az Android tervezésekor sok apróságot feláldoztak a gyorsaság és az egyszerűség oltárán, egy ilyen "apróság" a memória kezelés és az erőforrások elérése, a platform egy R.java forrásban gyűjti össze ez összes erőforrás elérhetőségét (ezt automatikusan generálja, nem kell szerkesztenünk!):

package hu.javaforum.android;
public final class R {
    public static final class attr {
    }
    public static final class layout {
        public static final int main=0x7f020000;
    }
    public static final class string {
        public static final int app_name=0x7f030000;
    }
}

Ezt a Java fájlt használhatjuk arra, hogy az ikonokat, képeket, elrendezéseket vagy szövegeket nem a programba írunk közvetlenül, hanem felhasználjuk az R osztályt, amely mutat az adott erőforrásra. Sok esetben találkozunk azzal, hogy nem a Java nyelvben megszokott módon adunk át egy példányra mutató referenciát, hanem magát a referenciát adjuk át, mint memóriacímet.

Ha megtekintjük újfent a HelloActivity  forrását, akkor láthatjuk, hogy mindössze egy metódust írtunk meg, vagyis definiáltunk felül:

package hu.javaforum.android;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class HelloActivity extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        TextView textView = new TextView(this);
        textView.setText("Hello, JavaForum.hu!");
        setContentView(textView);
    }
}

Az onCreate metódus egy a sok metódus közül, amelyet a platform hív meg: minden Activity példánynak van saját életciklusa és egymástól függetlenül élnek, ennek megértéséhez a legjobb egy folyamatábra:

Kövessük végig az ábrán egy Activity életének állomásait, amelyeket az életciklus különféle állapotai és eseményei hívnak meg:

A fenti hét metódus bármelyikét felül tudjuk definiálni az Activity leszármazottban, egyedül az onCreate metódusnak van egy Bundle paramétere, amely segítségével az alkalmazásunk ki tudja olvasni az előző futás végén elmentett paramétereket.

Egyelőre elégedjünk meg ennyivel, és nézzük meg jobban a felhasználók által látható felületet.