seeseekey.net - Invictus Deus Ex Machina

Bei AndEngine handelt es sich um eine Gameengine für Androidgeräte. Die Apps für diese Plattform werden ja bekanntlich in Java geschrieben. Und darum soll es hier auch gehen. Im ersten Schritt wird Eclipse aufgesetzt und anschließend nehmen wir die AndEngine in Betrieb. Im ersten Schritt muss also das Paket eclipse installiert werden. Danach sollte das Android SDK für Linux unter http://developer.android.com/sdk/index.html heruntergeladen werden und auf der Festplatte entpackt werden. Dann geht es in den Ordner tools des SDKs und dort wird dann

./android update sdk 

ausgeführt. Nun bestätigt man die Lizenz und installiert die verschiedenen SDK Versionen. Dies kann dabei einige Minuten dauern.

Nun kann man Eclipse starten. Beim ersten Start erscheint ein Begrüßungsbildschirm den man schließen kann. Danach sollte man unter Help -> Install new Software die Android Development Tools installieren. Dazu wird in dem sich öffnenden Dialog die URL http://dl-ssl.google.com/android/eclipse/ eingegeben und durch einen Druck auf den Add… Button hinzugefügt. Dann klicken wir die Checkbox Developer Tools an und betätigen die Installation mit dem Next… Button. Mittels eines Assistenten wird man nun durch die Installation geleitet. Nachdem die Installation beendet ist empfiehlt Eclipse einen Neustart der Umgebung. Diesem sollte Wunsch sollte man Folge leisten.

Nun benötigt Eclipse die Information wo das Android SDK sich auf der Festplatte befindet. Dazu geht man auf Window -> Preferences -> Android. Dort wählt man den Pfad des Android SDKs aus und bestätigt den Dialog mit OK.

Die grundlegende Konfigurationsarbeit ist damit geleistet. Nun kann mit dem ersten Projekt begonnen werden. Dazu gehen wir auf File -> New -> Project und wählen dort Android Project aus und klicken dann auf Next. In dem darauf folgenden Dialog geben wir dem Projekt 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. FormMain und bei Application name z.B. Hello World und bestätigen das ganze mit dem Finish Button.

Danach wird automatisch das Grundgerüst für eine Android Applikation erzeugt. Sollte es beim Erzeugen der Anwendung der Fehler

Project ‚RuntimeAndroid‘ is missing required source folder ‚gen’
The project cannot be built until build errors are resolved 

auftreten so hilft es die R.java Datei zu löschen. Sie wird danach automatisch neu erzeugt. Wenn wir nun auf den grünen Play Knopf (Run) in der Symbolleiste klicken so startet Eclipse das Programm im Android Emulator. Beim ersten Start sollte allerdings ein Dialog erscheinen welcher einem anbietet ein virtuelles Gerät für den Emulator anzulegen. Nachdem dies geschehen ist, wird das Hello World Programm im Emulator geladen und ausgeführt. Und schon ist das erste Hello World Programm geschrieben und die Funktionsfähigkeit der IDE getestet.

Nun geht es an die AndEngine. Erst einmal holen wir uns den Sourcecodes mittels hg (Mercurial) auf die Festplatte:

hg clone https://andengine.googlecode.com/hg/ andengine
hg clone https://andengineexamples.googlecode.com/hg/ andengineexamples 

Anschließend importieren wir das andengineexamples Projekt (File -> Import…) in den Workspace. In dem Projekt AndEngineExamples sind dabei viele Beispiele zur Anwendung der Engine zu finden.

Nun nehmen wir unser bereits angelegtes Hello World Projekt und erzeugen in diesem (mittels New -> Folder) einen Ordner namens lib. In diesen kopieren wir die andengine.jar aus dem AndEngine Examples Projekt. Nun klicken wir mit der rechten Maustaste auf die andengine.jar und wählen dort Build Path -> Add To Build Path… aus. Damit ist die Bibliothek referenziert. Nun gehen wir in unsere Activity, in diesem Fall FormMain und löschen dort alles bis auf die packages Zeile. Nun fügen wir dort folgenden Quelltext 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 werden mittels Strg + Shift + O alle benötigten Importe in die Datei eingefügt. Wichtig ist es jetzt noch dem Manifest folgende Zeile hinzuzufügen:

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

Nun kann man das ganze im Emulator starten. Es dürfte ein blauer Bildschirm angezeigt werden. Nun kann man sich damit beginnen das ganze mit Leben zu erfüllen :)

Weitere Informationen 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änden hat Eclipse nach der Installation eine systemspezifische Kodierung eingestellt. Für Windows ist dies z.B. Cp1252. Um Eclipse nun standardmäßig auf UTF-8 umzustellen geht man über Window -> Preferences in den Einstellungsdialog und dort in der linken Box auf General -> Workspace. Dort kann dann unter Text file encoding die Kodierung auf UTF-8 gestellt werden.

Sollte beim importieren eines Android Projektes folgende Fehlermeldung auftauchen:

Android requires .class compatibility set to 5.0. Please fix project properties.

so hilft es mit der rechten Maustaste auf das Projekt zu gehen und dann unter Android Tools -> Fix Projekt Properties das Projekt zu reparieren. Anschließend sollte Eclipse mit dem Projekt neugestartet werden. Der Fehler sollte danach nicht mehr auftreten.

Wenn man unter Eclipse Android Anwendungen debuggen möchte hat man es gar nicht so ein einfach. Jeder der das ausprobieren möchte sollte folgende Zeile in die onCreate Methode einer Activity hinzufügen (nach setContentView):

int error=7/0;

Diese Zeile führt zu einer Division durch Null Exception. Würde man sowas nun in C# machen und im Debugmodus ausführen so wird eine Exception ausgelöst und der Debugger zeigt genau die Stelle im Originalcode an an der der Fehler auftritt. So weiß man gleich wo der Fehler zu finden ist.

Wenn wir nun besagtes Beispiel in Eclipse im Debugmodus starten passiert jedoch etwas anderes. Der Debugger hält irgendwo in der Datei ActivityThread Datei an mit der Meldung das er den Source nicht finden kann. Also welche Möglichkeiten bleiben?

Das Debugfenster ist in diesem Moment auch nicht wirklich hilfreich. Ein wenig mehr hilft der LogCat View (wenn er nicht vorhanden ist, einfach über Window -> Show View -> Other hinzufügen) in die Exception angezeigt wird.

Bei unserer Exception müsste dort dann stehen:

Caused by: java.lang.ArithmeticException: divide by Zero

Darunter steht dann der Callstack inklusive Zeilennummer. Damit ist die Sache dann schon ein wenig angenehmer :)

Weitere Informationen 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 heraus eine andere Activity der Anwendung zu starten. Im Programm sind die Activities FormTodo und FormNotepad definiert. Im FormTodo existiert ein Button. Wenn dieser Button gedrückt wird soll die andere Activity gestartet werden. 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 Button drückt sollte die Activity gestartet werden. Ist dies nicht der Fall so fehlt meist die Definition der Activity im Android Manifest (AndroidManifest.xml).

Nein Mercedes bringt keine neue Klasse heraus :) Android schon. In jedem Projekt gibt es eine Datei namens R.java. Wenn man in die Datei hineinschaut findet man in etwa folgendes 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 Projekt definierten Ressourcen. Diese Datei wird dabei automatisch vom Android Plugin (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 deshalb niemals per Hand bearbeiten.

Mit Hilfe der R Klasse greift man auf die Ressourcen zu welche man angelegt hat, egal ob es sich nun z.B. um String oder Layout Ressourcen handelt.

Möchte man unter Eclipse den Workspace ändern so klickt man auf File -> Switch Workspace und ändert den Pfad. Sobald man das ganze bestätigt hat startet Eclipse neu. Möchte man das die Fenstereinstellungen etc. mit in den neuen Workspace übernommen werden, sollte man bei Copy Settings beide Checkboxen markieren. Allerdings gehen einige Einstellungen trotzdem verloren (z.B. der Pfad des Android SDK’s). Diese Einstellungen müssen dann abermals vorgenommen werden.

Wenn man Android Anwendungen mittels Eclipse programmiert so ist man auch in Besitz eines ausgewachsenen Debuggers, welcher einem bei der Fehlersuche hilfreich zur Seite steht. Damit wir etwas zum debuggen haben, bauen wir einen kleinen Fehler in unserer Hello World Programm 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 Programm starten stürzt es im Emulator ab, da eine Division durch Null nicht sehr beliebt ist. Um nun zu Debuggen müssen wir einen Breakpoint setzen. Diesen Breakpoint setzen wir an die Zeile int result = 42/0;. Ein Breakpoint wird gesetzt in dem man links von Quellcode auf der vertikalen Leiste eine Doppelklick vollführt.

Mittels Run -> Debug oder der F11 Taste starten wir das Programm im Debugmodus. Beim ersten Start im Debugmodus fragt uns Eclipse ob wir in die Debugansicht springen möchten was wir ablehnen. Das Programm startet dann ganz normal im Emulator bis der Debugger genau an der Stelle unterbricht wo wir den Breakpoint gesetzt haben.

Nun könnten wir z.B. den Term 42/0 in das Expression Fenster ziehen (Window -> Show View -> Other… -> Debug -> Expressions) und sehen dann das bei der Operation eine Divide by Zero herauskommt.

In dem View Debug befinden sich außerdem die Controls um durch das Programm oder in Funktionen hinein zu steppen. Soviel zum Debugging mittels Eclipse und Android :)

Heute wollen wir das Hello World Programm was in dem letzten Artikel beschrieben wurde ein klein wenig unter die Lupe nehmen. Dazu öffnen wir das Projekt erst einmal in Eclipse. Nachdem dies geschafft ist schauen wir uns die Datei hello_world.java an. Dort finden wir folgenden 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 abgeleitet. Bei Activity handelt es sich um eine Klasse welche für Standard GUI Anwendungen vorgesehen ist. Oder um Heise zu zitieren:

Im Android-Umfeld bezeichnet er eine lauffähige Einheit, also die Startklasse der Anwendung. Das Plug-in generiert daraus eine von android.app abgeleitete Klasse des angegebenen Namens.

Doch schauen wir uns erstmal unser Projekt an. Im großen und ganzen gibt es drei Ordner im Projekt, src, assets und res.

Im src befindet sich der Quellcode der Anwendung, der assets Ordner ist im leer und im res Ordner befinden sich drei Unterordner: drawable, layout und values. In dem Ordner drawable befinden sich die Grafiken in dem Ordner layout befindet sich das Layout (in einer XML Beschreibung) und im Ordner values stehen z.B. die Strings für Beschriftungen (bzw. in der values.xml).

Wer sich über die Datei R.java wundert. Diese Datei verknüpft die Ressourcen mit dem Programmcode. Sie braucht auch nicht angefasst werden, da sie stets automatisch erzeugt wird.

Weitere Informationen gibt es unter:
http://www.heise.de/developer/artikel/print/120124