seeseekey.net - Invictus Deus Ex Machina

Bei AndEn­gine han­delt es sich um eine Game­en­gine für Andro­id­ge­räte. Die Apps für diese Platt­form wer­den ja bekannt­lich in Java geschrie­ben. Und darum soll es hier auch gehen. Im ers­ten Schritt wird Eclipse auf­ge­setzt und anschlie­ßend neh­men wir die AndEn­gine in Betrieb. Im ers­ten Schritt muss also das Paket eclipse instal­liert wer­den. Danach sollte das Android SDK für Linux unter http://developer.android.com/sdk/index.html her­un­ter­ge­la­den wer­den und auf der Fest­platte ent­packt wer­den. Dann geht es in den Ord­ner tools des SDKs und dort wird dann

./android update sdk 

aus­ge­führt. Nun bestä­tigt man die Lizenz und instal­liert die ver­schie­de­nen SDK Ver­sio­nen. Dies kann dabei einige Minu­ten dauern.

Nun kann man Eclipse star­ten. Beim ers­ten Start erscheint ein Begrü­ßungs­bild­schirm den man schlie­ßen kann. Danach sollte man unter Help -> Install new Soft­ware die Android Deve­lop­ment Tools instal­lie­ren. Dazu wird in dem sich öff­nen­den Dia­log die URL http://dl-ssl.google.com/android/eclipse/ ein­ge­ge­ben und durch einen Druck auf den Add… But­ton hin­zu­ge­fügt. Dann kli­cken wir die Check­box Deve­l­oper Tools an und betä­ti­gen die Instal­la­tion mit dem Next… But­ton. Mit­tels eines Assis­ten­ten wird man nun durch die Instal­la­tion gelei­tet. Nach­dem die Instal­la­tion been­det ist emp­fiehlt Eclipse einen Neu­start der Umge­bung. Die­sem sollte Wunsch sollte man Folge leisten.

Nun benö­tigt Eclipse die Infor­ma­tion wo das Android SDK sich auf der Fest­platte befin­det. Dazu geht man auf Win­dow -> Pre­fe­ren­ces -> Android. Dort wählt man den Pfad des Android SDKs aus und bestä­tigt den Dia­log mit OK.

Die grund­le­gende Kon­fi­gu­ra­ti­ons­ar­beit ist damit geleis­tet. Nun kann mit dem ers­ten Pro­jekt begon­nen wer­den. Dazu gehen wir auf File -> New -> Pro­ject und wäh­len dort Android Pro­ject aus und kli­cken dann auf Next. In dem dar­auf fol­gen­den Dia­log geben wir dem Pro­jekt einen Namen z.B. Hello World. Im Feld Package Name geben wir den Namen des Package an z.B. net.seeseekey.hello_world und bei Activity name z.B. Form­Main und bei App­li­ca­tion name z.B. Hello World und bestä­ti­gen das ganze mit dem Finish Button.

Danach wird auto­ma­tisch das Grund­ge­rüst für eine Android Appli­ka­tion erzeugt. Sollte es beim Erzeu­gen der Anwen­dung der Fehler

Pro­ject ‚Run­ti­me­An­droid‘ is mis­sing requi­red source fol­der ‚gen’
The pro­ject can­not be built until build errors are resolved 

auf­tre­ten so hilft es die R.java Datei zu löschen. Sie wird danach auto­ma­tisch neu erzeugt. Wenn wir nun auf den grü­nen Play Knopf (Run) in der Sym­bolleiste kli­cken so star­tet Eclipse das Pro­gramm im Android Emu­la­tor. Beim ers­ten Start sollte aller­dings ein Dia­log erschei­nen wel­cher einem anbie­tet ein vir­tu­el­les Gerät für den Emu­la­tor anzu­le­gen. Nach­dem dies gesche­hen ist, wird das Hello World Pro­gramm im Emu­la­tor gela­den und aus­ge­führt. Und schon ist das erste Hello World Pro­gramm geschrie­ben und die Funk­ti­ons­fä­hig­keit der IDE getestet.

Nun geht es an die AndEn­gine. Erst ein­mal holen wir uns den Source­codes mit­tels hg (Mer­cu­rial) auf die Festplatte:

hg clone https://andengine.googlecode.com/hg/ anden­gine
hg clone https://andengineexamples.googlecode.com/hg/ andengineexamples 

Anschlie­ßend impor­tie­ren wir das anden­gi­neexam­ples Pro­jekt (File -> Import…) in den Works­pace. In dem Pro­jekt AndEn­gi­neExam­ples sind dabei viele Bei­spiele zur Anwen­dung der Engine zu finden.

Nun neh­men wir unser bereits ange­leg­tes Hello World Pro­jekt und erzeu­gen in die­sem (mit­tels New -> Fol­der) einen Ord­ner namens lib. In die­sen kopie­ren wir die andengine.jar aus dem AndEn­gine Exam­ples Pro­jekt. Nun kli­cken wir mit der rech­ten Maus­taste auf die andengine.jar und wäh­len dort Build Path -> Add To Build Path… aus. Damit ist die Biblio­thek refe­ren­ziert. Nun gehen wir in unsere Activity, in die­sem Fall Form­Main und löschen dort alles bis auf die packa­ges Zeile. Nun fügen wir dort fol­gen­den Quell­text ein:

public class FormMain extends BaseGameActivity {
	// Konstanten
	private static final int CAMERA_WIDTH = 720;
	private static final int CAMERA_HEIGHT = 480;

	// Variablen
	private Camera mCamera;

	@Override
	public Engine onLoadEngine() {
		this.mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
		return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.mCamera));
	}

	@Override
	public void onLoadResources() {
	}

	@Override
	public Scene onLoadScene() {
		this.mEngine.registerUpdateHandler(new FPSLogger());

		final Scene scene = new Scene(1);
		scene.setBackground(new ColorBackground(0, 0, 0.8784f));

		return scene;
	}

	@Override
	public void onLoadComplete() {

	}
}

Anschlie­ßend wer­den mit­tels Strg + Shift + O alle benö­tig­ten Importe in die Datei ein­ge­fügt. Wich­tig ist es jetzt noch dem Mani­fest fol­gende Zeile hinzuzufügen:

<uses-permission android:name="android.permission.WAKE_LOCK"/>

Nun kann man das ganze im Emu­la­tor star­ten. Es dürfte ein blauer Bild­schirm ange­zeigt wer­den. Nun kann man sich damit begin­nen das ganze mit Leben zu erfül­len :)

Wei­tere Infor­ma­tio­nen gibt es unter:
http://www.andengine.org/
http://code.google.com/p/andengine/
http://code.google.com/p/andengineexamples/
http://developer.android.com/sdk/installing.html
http://www.andengine.org/forums/tutorials/getting-started-updated-t2198.html
http://www.andengine.org/forums/tutorials/andengine-core-terminology-t316.html
http://www.andengine.org/forums/tutorials/getting-started-with-andengine-t11.html
http://www.andengine.org/forums/tutorials/eclipse-andengine-and-helloworld-t380.html
http://www.andengine.org/forums/tutorials/mimminito-s-tutorial-list-t417.html

Unter Umstän­den hat Eclipse nach der Instal­la­tion eine sys­tem­spe­zi­fi­sche Kodie­rung ein­ge­stellt. Für Win­dows ist dies z.B. Cp1252. Um Eclipse nun stan­dard­mä­ßig auf UTF-8 umzu­stel­len geht man über Win­dow -> Pre­fe­ren­ces in den Ein­stel­lungs­dia­log und dort in der lin­ken Box auf Gene­ral -> Works­pace. Dort kann dann unter Text file enco­ding die Kodie­rung auf UTF-8 gestellt werden.

Sollte beim impor­tie­ren eines Android Pro­jek­tes fol­gende Feh­ler­mel­dung auf­tau­chen:

Android requi­res .class com­pa­ti­bi­lity set to 5.0. Please fix pro­ject properties.

so hilft es mit der rech­ten Maus­taste auf das Pro­jekt zu gehen und dann unter Android Tools -> Fix Pro­jekt Pro­per­ties das Pro­jekt zu repa­rie­ren. Anschlie­ßend sollte Eclipse mit dem Pro­jekt neu­ge­star­tet wer­den. Der Feh­ler sollte danach nicht mehr auftreten.

Wenn man unter Eclipse Android Anwen­dun­gen debug­gen möchte hat man es gar nicht so ein ein­fach. Jeder der das aus­pro­bie­ren möchte sollte fol­gende Zeile in die onCreate Methode einer Activity hin­zu­fü­gen (nach set­Con­tent­View):

int error=7/0;

Diese Zeile führt zu einer Divi­sion durch Null Excep­tion. Würde man sowas nun in C# machen und im Debug­mo­dus aus­füh­ren so wird eine Excep­tion aus­ge­löst und der Debug­ger zeigt genau die Stelle im Ori­gi­nal­code an an der der Feh­ler auf­tritt. So weiß man gleich wo der Feh­ler zu fin­den ist.

Wenn wir nun besag­tes Bei­spiel in Eclipse im Debug­mo­dus star­ten pas­siert jedoch etwas ande­res. Der Debug­ger hält irgendwo in der Datei Activi­ty­Th­read Datei an mit der Mel­dung das er den Source nicht fin­den kann. Also wel­che Mög­lich­kei­ten bleiben?

Das Debug­fens­ter ist in die­sem Moment auch nicht wirk­lich hilf­reich. Ein wenig mehr hilft der Log­Cat View (wenn er nicht vor­han­den ist, ein­fach über Win­dow -> Show View -> Other hin­zu­fü­gen) in die Excep­tion ange­zeigt wird.

Bei unse­rer Excep­tion müsste dort dann ste­hen:

Cau­sed by: java.lang.ArithmeticException: divide by Zero

Dar­un­ter steht dann der Call­stack inklu­sive Zei­len­num­mer. Damit ist die Sache dann schon ein wenig ange­neh­mer :)

Wei­tere Infor­ma­tio­nen gibt es unter:
http://www.anddev.org/a_solution_for_source_not_found_in_eclipse-t3151.html

Heute soll es darum gehen, aus einer Activity her­aus eine andere Activity der Anwen­dung zu star­ten. Im Pro­gramm sind die Activi­ties Form­Todo und Form­No­te­pad defi­niert. Im Form­Todo exis­tiert ein But­ton. Wenn die­ser But­ton gedrückt wird soll die andere Activity gestar­tet wer­den. Das ganze sieht dann so aus:

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.todo);
        
        Button okButton = (Button) findViewById(R.id.btnNotices);
        okButton.setOnClickListener(new View.OnClickListener() {
          public void onClick(View view) {
        	  
          	Intent intent = new Intent();	
        	intent.setClass(FormTodo.this, FormNotepad.class);		
        	startActivity(intent);
          }
        });
    }

Wenn man nun auf den But­ton drückt sollte die Activity gestar­tet wer­den. Ist dies nicht der Fall so fehlt meist die Defi­ni­tion der Activity im Android Mani­fest (AndroidManifest.xml).

Nein Mer­ce­des bringt keine neue Klasse her­aus :) Android schon. In jedem Pro­jekt gibt es eine Datei namens R.java. Wenn man in die Datei hin­ein­schaut fin­det man in etwa fol­gen­des vor:

package net.seeseekey.hello_world;

public final class R {
public static final class attr {
}
public static final class drawable {
public static final int icon=0x7f020000;
}
public static final class layout {
public static final int main=0x7f030000;
}
public static final class string {
public static final int app_name=0x7f040001;
public static final int hello=0x7f040000;
}
}

Was wir dort sehen ist ein Index aller im Pro­jekt defi­nier­ten Res­sour­cen. Diese Datei wird dabei auto­ma­tisch vom Android Plu­gin (wenn man Eclipse benutzt) erzeugt. Wird Eclipse nicht benutzt so wird diese Datei jeweils zur Build Time mit Hilfe von Ant neu erzeugt. Man sollte die R.java Datei auch des­halb nie­mals per Hand bearbeiten.

Mit Hilfe der R Klasse greift man auf die Res­sour­cen zu wel­che man ange­legt hat, egal ob es sich nun z.B. um String oder Lay­out Res­sour­cen handelt.

Möchte man unter Eclipse den Works­pace ändern so klickt man auf File -> Switch Works­pace und ändert den Pfad. Sobald man das ganze bestä­tigt hat star­tet Eclipse neu. Möchte man das die Fens­ter­ein­stel­lun­gen etc. mit in den neuen Works­pace über­nom­men wer­den, sollte man bei Copy Set­tings beide Check­bo­xen mar­kie­ren. Aller­dings gehen einige Ein­stel­lun­gen trotz­dem ver­lo­ren (z.B. der Pfad des Android SDK’s). Diese Ein­stel­lun­gen müs­sen dann aber­mals vor­ge­nom­men werden.

Wenn man Android Anwen­dun­gen mit­tels Eclipse pro­gram­miert so ist man auch in Besitz eines aus­ge­wach­se­nen Debug­gers, wel­cher einem bei der Feh­ler­su­che hilf­reich zur Seite steht. Damit wir etwas zum debug­gen haben, bauen wir einen klei­nen Feh­ler in unse­rer Hello World Pro­gramm ein. Das ganze sieht dann so aus:

package net.seeseekey.hello_world;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class hello_world extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

int result = 42/0;

TextView tv = new TextView(this);
tv.setText(result);
setContentView(tv);
}
}

Wenn wir das Pro­gramm star­ten stürzt es im Emu­la­tor ab, da eine Divi­sion durch Null nicht sehr beliebt ist. Um nun zu Debug­gen müs­sen wir einen Bre­ak­point set­zen. Die­sen Bre­ak­point set­zen wir an die Zeile int result = 42/0;. Ein Bre­ak­point wird gesetzt in dem man links von Quell­code auf der ver­ti­ka­len Leiste eine Dop­pel­klick vollführt.

Mit­tels Run -> Debug oder der F11 Taste star­ten wir das Pro­gramm im Debug­mo­dus. Beim ers­ten Start im Debug­mo­dus fragt uns Eclipse ob wir in die Debu­gan­sicht sprin­gen möch­ten was wir ableh­nen. Das Pro­gramm star­tet dann ganz nor­mal im Emu­la­tor bis der Debug­ger genau an der Stelle unter­bricht wo wir den Bre­ak­point gesetzt haben.

Nun könn­ten wir z.B. den Term 42/0 in das Expres­sion Fens­ter zie­hen (Win­dow -> Show View -> Other… -> Debug -> Expres­si­ons) und sehen dann das bei der Ope­ra­tion eine Divide by Zero herauskommt.

In dem View Debug befin­den sich außer­dem die Con­trols um durch das Pro­gramm oder in Funk­tio­nen hin­ein zu step­pen. Soviel zum Debug­ging mit­tels Eclipse und Android :)

Heute wol­len wir das Hello World Pro­gramm was in dem letz­ten Arti­kel beschrie­ben wurde ein klein wenig unter die Lupe neh­men. Dazu öff­nen wir das Pro­jekt erst ein­mal in Eclipse. Nach­dem dies geschafft ist schauen wir uns die Datei hello_world.java an. Dort fin­den wir fol­gen­den Code vor:

package net.seeseekey.hello_world;

import android.app.Activity;
import android.os.Bundle;

public class hello_word extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

Wie man sieht wird die Klasse hello_world von der Klasse Activity abge­lei­tet. Bei Activity han­delt es sich um eine Klasse wel­che für Stan­dard GUI Anwen­dun­gen vor­ge­se­hen ist. Oder um Heise zu zitie­ren:

Im Android-Umfeld bezeich­net er eine lauf­fä­hige Ein­heit, also die Start­klasse der Anwen­dung. Das Plug-in gene­riert dar­aus eine von android.app abge­lei­tete Klasse des ange­ge­be­nen Namens.

Doch schauen wir uns erst­mal unser Pro­jekt an. Im gro­ßen und gan­zen gibt es drei Ord­ner im Pro­jekt, src, assets und res.

Im src befin­det sich der Quell­code der Anwen­dung, der assets Ord­ner ist im leer und im res Ord­ner befin­den sich drei Unter­ord­ner: dra­wable, lay­out und values. In dem Ord­ner dra­wable befin­den sich die Gra­fi­ken in dem Ord­ner lay­out befin­det sich das Lay­out (in einer XML Beschrei­bung) und im Ord­ner values ste­hen z.B. die Strings für Beschrif­tun­gen (bzw. in der values.xml).

Wer sich über die Datei R.java wun­dert. Diese Datei ver­knüpft die Res­sour­cen mit dem Pro­gramm­code. Sie braucht auch nicht ange­fasst wer­den, da sie stets auto­ma­tisch erzeugt wird.

Wei­tere Infor­ma­tio­nen gibt es unter:
http://www.heise.de/developer/artikel/print/120124