Versionierungsstrategien


Versionierungsstrategien
Zum Original Blog WebDucer techBlog

Artikeldaten
Erste Version 0.1 (22.08.2012)
Aktuelle Version 0.1(22.08.2012)

1. Kurzbeschreibung

Bei der Software-Entwicklung (und auch beim Schreiben von größeren Texten) ist es sinnvoll von Zeit zu Zeit den aktuellen Entwicklungsstand zu sichern. Am Anfang reicht hierfür vielleicht die Kopie des Projektordners auf einer externen Festplatte (in z.B. einen Unterordner mit dem Zeitstempel als Namen). Irgendwann wird dies aber zu umständlich und zu unübersichtlich. Es wird Zeit über ein Versionierungssystem nachzudenken und damit auch über eine Versionierungsstrategie. Dieser Artikel soll bei dieser Entscheidung helfen. Die vorgestellten Strategien sind unabhängig von dem eingesetzten Versionierungssystem (Git, TFS, Subversion, Mercurial usw.).

2. Ein-Zweig Strategie

Versionsstrategien - Ein-Zweig

2.1. Beschreibung

Diese Strategie ist relativ einfach. Alle Änderungen werden in einen einzigen Zweig abgelegt. Sobald der Code einen Release-Status erreicht hat, wird dieser Stand ausgeliefert und mit einem sprechenden Namen (meistens Versionsnummer) versehen. Damit ist diese Release-Version jederzeit in der eigenen Versionsverwaltung schnell auffindbar. Nach der Auslieferung der Release-Version geht die Entwicklung linear weiter.

2.2. Pro

  • Sehr einfache Benutzung
  • Kein Merge zwischen unterschiedlichen Zweigen notwendig
  • Sehr gut für den Einstieg in die Versionsverwaltung geeignet
  • Sehr gut für Dokument-Versionierung (Bücher, Artikel, Manuskripte usw.)

2.3. Kontra

  • Schwer zu handhaben, wenn mehr als nu rein Entwickler beteilig ist, da während des Release-Tests keine Weiterentwicklung für nächste Version möglich ist.
  • Hotfixes einer Version sind sehr schwer zu realisieren, da eventuell bereits unvollständige Features für neue Version da sind.

3. Master-Develop Strategie

Versionsstrategien - Master-Develop

3.1. Beschreibung

Diese Strategie ist auch relativ einfach. Das eigene Versionsverwaltungssystem besteht aus zwei Zweigen. In dem Master-Zweig werden nur benannte, getestete und abgeschlossene Versionen abgelegt (z.B. Stand einer Release-Version). Der Develop-Zweig wird dagegen wie in der Ein-Strang-Strategie benutzt. Alle Projektstände, die gesichert werden sollten (egal ob der Stand vollständig und / oder lauffähig ist), werden diese in den Develop-Zweig geschrieben. Ist ein Code / Text-Stand erreicht, der an den Kunden ausgeliefert werden kann, und ist getestet, wird der Master-Zweig mit dem Develop-Zweig zusammengeführt. Danach wird der Stand des Master-Zweiges benannt (z.B. mit Versionsnummer).

3.2. Pro

  • Bietet besseren Überblick über ausgelieferte / veröffentlichte Projektstände und belässt die Flexibilität bei der täglichen Arbeit.
  • Schneller Zugriff auf benannte Stände, da diese nur im Master-Zweig vertreten sind (ohne Entwicklungsbalast).

3.3. Kontra

  • Schwer zu handhaben, wenn mehr als nur ein Entwickler beteilig ist, da während des Release-Tests keine Weiterentwicklung für nächste Version möglich ist.
  • Hotfixes einer Version sind sehr schwer zu realisieren, da eventuell bereits unvollständige Features für neue Version da sind.

4. Git-flow Strategie

Versionsstrategien - Git flow

4.1. Beschreibung

Diese Strategie ist mit Git-Versionsverwaltung entstanden, da bei Git die Zweige (branches) sehr einfach erstellt und wieder gelöscht werden könne. Hier werden zwei Arten der Zweige verwendet.

imortal branches (unsterbliche Zweige)
Das sind Zweige, die über die gesamte Dauer des Projektes bestehen bleiben. Zu solchen Zweigen gehören bei Git-Flow-Strategie master und develop Zweige
mortal branches (sterbliche Zweige)
Das sind Zweige, die nur eine begrenzte Lebensdauer haben und nach dem Erfüllen des Zwecks, gelöscht werden (können). Zu solchen Zweigen gehören bei Git-Flow-Strategie die release, hotfix und feature Zweige.

feature

Auf dem “develop“-Zweig werden direkt nur sehr kleine Änderungen gemacht. Größere Änderungen werden in eigene sterbliche Zweige ausgelagert, die mit dem Präfix “feature” anfangen (Ursprung ist “develop“-Zweig). Die Entwicklung der neuen Funktion erfolgt dann bis zur Fertigstellung auf diesem sterblichen Zweig. In der Zwischenzeit kann man diesen “feature“-Zweig mit “develop“-Zweig abgleichen, um die Unterschiede klein zu halten, oder bestimmte bereits bereinigte Fehler auch in diesem Zweig zu korrigieren. Nach dem Beenden der neuen Funktion wird der “develop“-Zweig mit dem “feature“-Zweig zusammengeführt und der “feature“-Zweig gelöscht.

  1. Neuen Zweig mit Namen “feature/bezeichnung” erstellen.
  2. Entwicklung auf dem neuen Zweig “feature/bezeichnung“.
  3. Develop-Zweig mit dem neuen Zweig “feature/bezeichnung“ zusammenführen, sobald die Aufgabe erledigt ist.
  4. Den neuen Zweig “feature/bezeichnung“ löschen.

release

Ist ein Stand auf dem “develop“-Zweig erreicht, der ausgeliefert werden kann, wird ein sterblicher “release“-Zweig aufgemacht (Ursprung ist “develop“-Zweig). Dieser hat den Präfix “release“. Dieser Zweig dient dem Testen des fertigen Standes, ohne die Entwicklung auf dem “develop“-Zweig zu beeinträchtigen. Wenn die Tests Fehler zum Vorschein bringen, werden diese im “release“-Zweig korrigiert, bis der Stand wirklich ausgeliefert werden kann. Dann wird dieser Stand mit “master“-Zweig zusammengeführt und ein neuer Tag auf dem “master“-Zweig erstellt. Danach wird der “develop“-Zweig mit dem “release“-Zweig zusammengeführt. Abschließend wird der sterbliche “release“-Zweig gelöscht.

  1. Neuen Zweig mit Namen “release/vVersionNummer” erstellen.
  2. Tests und Bugfixing auf dem neuen Zweig “release/vVersionNummer“ durchführen.
  3. Nach allen Tests und Korrekturen den Master-Zweig mit dem neuen Zweig “release/vVersionNummer“ zusammenführen.
  4. Master-Zweig-Stand benennen (tagen).
  5. Develop-Zweig mit dem neuen Zweig “release/vVersionNummer“ zusammenführen.
  6. Den neuen Zweig “release/vVersionNummer“ löschen.

hotfix

Die ausgelieferten Versionen sind meistens trotzt vieler Tests nicht frei von Fehlern. In solchen Fällen wird aus dem “master“-Zweig ein neuer sterblicher “hotfix“-Zweig erstellt, um den Fehler zu korrigieren. Dieser Zweig hat das Präfix “hotfix” und erfüllt nur eine einzige Aufgabe, den gefundenen Fehler der Version zu korrigieren. Durch den eigenen Zweig für Fehlerkorrektur wird der Entwicklungsfluss nicht beeinträchtigt. Sobald der Fehler (oder auch mehrere) korrigiert wurde, wird der “master“-Zweig mit dem “hotfix“-Zweig zusammengeführt und neu getagt (benannt). Die Fehlerkorrektur muss auch in den “develop“-Zweig. Aus diesem Grund wird auch der “develop“-Zweig mit dem “hotfix“-Zweig zusammengeführt. Abschließend wird der “hotfix“-Zweig gelöscht.

  1. Neuen Zweig mit Namen “hotfix/vVersionNummer” erstellen.
  2. Fehlerkorrekturen auf dem neuen Zweig “hotfix/vVersionNummer“ durchführen und testen.
  3. Nach der erfolgreichen Korrektur der Fehler den Master-Zweig mit dem neuen Zweig “hotfix/vVersionNummer“ zusammenführen.
  4. Master-Zweig-Stand benennen (tagen).
  5. Develop-Zweig mit dem neuen Zweig “hotfix/vVersionNummer“ zusammenführen.
  6. Den neuen Zweig “hotfix/vVersionNummer“ löschen.

4.2. Pro

  • Arbeiten im Team ohne Beeinträchtigungen möglich, da Aufgaben in eigenen Zweigen erledigt werden.
  • Saubere Implementierung der Hotfixes für Release-Versionen ohne Beeinträchtigung der Entwicklung möglich.
  • Paralelles Weiterentwicklen der nächsten Version und vorbereiten (testen) der aktuellen durch Release-Zweige möglich.
  • Auslieferung von Hotfixes in sehr kurzer Zeit möglich, da keine Rücksicht auf den Entwicklungsstand genommen werden muss.

4.3. Kontra

  • Komplexere Handhabung als beide vorhergehenden Strategien.
  • Momentan wird nur von wenigen graphischen Tools (z.B.: SourceTree unter OS X) direkt unterstützt.
  • Erfordert Disziplin beim Entwickeln, da für jede Aufgabe ein neuer Zweig aufgemacht werden muss.
  • Nicht geeignet, wenn mehrere Release-Versionen über lange Zeiträume parallel gepflegt werden müssen.

5. Ressourcen

5.1. Bilder

Versionsstrategien - Ein-Zweig
Versionsstrategien - Master-Develop
Versionsstrategien - Git flow

5.2. Links

5.3. Bücher

Zum Original Blog
Autor: WebDucer

Edu-Store mit bis zu 85% Rabatt

Android: Einfache Perfomance-Optimierungen


Android: Einfache Perfomance-Optimierungen
Zum Original Blog WebDucer techBlog

  1. Zugriff auf Klassenvariablen (Eigenschaften) sollte, wenn möglich (z.B. innerhalb der Klasse oder des Packages), direkt über die Klassenvariablen statt über die Getter und Setter-Methoden erfolgen. Performance-Steigerung liegt ca. beim Faktor 2-3.
  2. Bei Zusammenfügen von String-Ketten  sollte man den StringBulder, statt des „+“-Operators nutzen. Mit der Anzahl der Konkatenationen steigt der Performance-Verlust beim „+“-Operator exponentiell an, da jedes Mal ein neues Objekt erzeugt werden muss. Beim StringBuilder steigt die Rechenzeit dagegen nur linear an.
  3. Es sollen unnötige Objekterzeugungen vermieden werden. So z.B.:
    1. Objekterzeugung innerhalb der Schleifen vermeiden
    2. Mehrfache Objekterzeugung von oft benutzen Objekten in der Klasse vemeiden (z.B.: findViewById()). Diese sollten am besten direkt als Klassenvariablen, und somit nur einmal, initialisiert werden.
  4. Schleifen optimieren. Satt:
    for (int i = 0; i < array.length; i++) { … }

    sollte

    int arrayLenght = array.length;
    for (int i = 0; i < arrayLength; i++) { … }

    verwendet werden.

  5. Layoutoptimierung mit dem mitgelieferten Tool layoutopt durchführen.
  6. Größere (mehr als 100 Elemente) Arrays sind deutlich perfomanter als ArrayList Objekte.
  7. Einfache Klassen, sollten wenn möglich durch Arrays ersetzt werden, da dadurch die Objekterzeugung entfällt.
  8. Wenn möglich, sollten final und static Zugriffsmodifizierer verwendet werden.
  9. Die Schleifen, nach dem das gewünschte Ergebnis erreicht wurde, sollten durch break oder continue verlassen werden und nicht unnötig die restlichen Elemente durchlaufen.
  10. Rechenintensive oder Zeitintensive Aufgaben (z.B.: Netzwerk und Dateizugriffe) sollten immer in ein eigenes Thread ausgelagert werden, damit der Benutzer weiterhin die Kontrolle über die App behält.
  11. Beim WebServices und Netzwerkzugriffen sollte dem kompakteren JSON-Format immer der Vorzug vor dem XML-Format gewährt werden (kleinerer Overhead).
  12. Benutzung des mitgelieferten Obfuscators ProGuard, um den kompilierten Code zu optimieren (Komprimierung von Code, weglassen unbenutzer Methoden / Eigenschaften / Klassen, kürzung der Bezeichner usw.).
  13. Test der eigenen Algorithmen auf Perfomance und Test der Alternativen (Benchmarking).
  14. Benutzung von TraceView (DDMS), um Flaschenhälse beim Speicher und Ausführungszeit zu finden.
  15. Bei den SQL-Abfragen sollten nur die wirklich notwendige Daten abgefragt werden (nur benötigte Spalten und nur die benötigte Datenmenge, Zeilenanzahl).
  16. Lint nutzen, um unbenutzte Resourcen und vorgeschlagene Optimierungen umzusetzen.

Zum Original Blog
Autor: WebDucer

Android: Erste App (Währungsrechner) – Teil 2

Backlinkseller

Android: Erste App (Währungsrechner) – Teil 2
Zum Original Blog WebDucer techBlog

Den ersten Teil des Workshops finden Sie unter “Android: Erste App (Währungsrechner) – Teil 1“.

Unsere App ist bereits lauffähig. Aber es fehlt noch ein entscheidender Punkt, bevor wir uns der Programmlogik annehmen. Die beiden Auswahlboxen sind momentan ohne Inhalt und somit zwecklos. Das wollen wir natürlich ändern.

Die Auswahlboxen können als Inhalt Daten aus einer Datenbank oder aus einem Array (Auflistung) entgegennehmen. Da wir später noch unsere App mehrsprachig machen wollen, werden wir die Währungen als Ressourcen ablegen.
Android Tools
Ressource File
Array Ressource
Spinner
Localization Ressource
Währungsapp

Dafür befolgen Sie die folgenden Schritte:

  1. Klicken Sie mit der rechten Maustaste auf das Projekt in der Package-Explorer Ansicht.
  2. Wählen Sie den Punkt “Android Tools” (ganz unten im Kontextmenü).
  3. Wählen Sie im Untermenü “New Resource File ...“.
  4. Geben Sie als File “arrays” ein.
  5. Wählen Sie als Typ “Values” aus.
  6. Klicken Sie auf “Finish“.

Damit legen wir eine neue Ressource-Datei, in der wir Auflistungen speichern werden. Wir benötigen insgesamt 2 Auflistungen. In der neuen Datei legen Sie entweder über die graphische Oberfläche über den “Add” Knopf ein neues StringArray (siehe Bilder) mit dem Namen “waehrung“, oder Sie geben die Werte direkt als XML-Code ein. Die XML-Darstellungen sehen Sie weiter unten.

array.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="waehrung">
        <item>EUR - Euro</item>
        <item>USD - Amerikanische Dollar</item>
        <item>AUD - Australische Dollar</item>
        <item>RUB - Russische Rubel</item>
        <item>CUD - Kanadische Dollar</item>
        <item>GBP - Englische Pfund</item>
    </string-array>
    <string-array name="waehrung_kurs">
        <item>1</item>
        <item>1.3795</item>
        <item>1.3314</item>
        <item>42.1941</item>
        <item>1.3495</item>
        <item>0.8738</item>
    </string-array>
</resources>

Nun können wir die beiden Auswahllisten mit dem Inhalt der ersten Auslistung füllen. Die zweite Liste benötigen wir später im Code. Es sind die Währungskurse in Bezug auf Euro, die wir für die Umrechnung benötigen.

Um die Auswahlliste an eine Auflistung zu binden, müssen wir nur in unseren Layout-Datei “main.xml” bei den beiden Auswahllisten (Spinner) folgende Zeile (Zeile Nr. 6) hinzufügen.

<Spinner
	android:layout_height="wrap_content"
	android:layout_width="0dp"
	android:layout_weight="1"
	android:id="@+id/selWaehrungStart"
	android:entries="@array/waehrung">
</Spinner>

Wenn Sie jetzt die App starten, können Sie bereits die Ausgangs- und Zielwährung wählen (siehe Bild).

Nun können wir uns den Java-Quellcode widmen. Als Erstes sollte unser “Berechnen” Knopf auf das Klicken reagieren. Dazu registrieren wir einen Listener (Zuhörer), der praktisch darauf wartet, bis der Benutzer eine Aktion ausführt. Dazu müssen wir als Erstes die Instanz des Knopfes ermitteln. Nun kommt uns zugute, dass wir unsere Views mit einer eindeutigen ID versehen haben.

Aus dem Java Code zu einer Activity könne wir jederzeit eine Referenz auf ein View mit einer ID ermitteln. Dafür stellt die Activity die Methode findViewById(ID). Da die Methode die Basisklasse “View” zurückliefert, müssen wir den Rückgabewert noch auf das zu erwartende View (in unserem Fall Button) kasten (Button cmdBerechnen = (Button)findViewById(R.id.cmdBerechnen);). Wie an diesem Beispiel zu sehen ist, greifen wir auf die automatisch generierte “R“-Klasse, die uns die Referenzen auf unsere Ressourcen zur Verfügung stellt. Dabei sind folgende oft verwendete Referenzen wichtig:

  • R.id : Referenzen auf die Views der Layouts. Im Layout sind das die android:id="" Attribute
  • R.layout : Referenzen auf die Layout-Dateien
  • R.string : Referenzen auf unsere definierten Texte
  • R.array : Referenzen auf unsere definierte Auflistungen
  • R.color : Referenzen auf die Farben
  • R.drawable : Referenzen auf die Bilder
  • und einige weitere. Weitere Infos dazu finden Sie unter: developer.android.com

Den Listener fügen Sie mit der folgen Zeile hinzu:

cmdBerechnen.setOnClickListener(new OnClickListener() {
	public void onClick(View v) {
		kursBerechnen();
	}
});

Wir rufen in diesem unsere eigene Methode auf, die die Berechnung und die Ausgabe übernimmt. Das Ganze passiert in der onCreate Methode, die beim Erstellen einer Activity als Erstes aufgerufen wird (Lebenszyklen einer Activity wird in einem anderen Workshop erklärt). Schauen wir uns diese genauer an.

HauptActivity.java

package de.webducer.android.wrechner;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

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

        Init();
    }

    /**
     * Initialisierung des Menüs (wird nur ein mal aufgerufen)
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    	MenuInflater inflater = new MenuInflater(this);
    	inflater.inflate(R.menu.menu, menu);
    	return super.onCreateOptionsMenu(menu);
    }

    /**
     * Reagieren auf ein Klick auf ein Menüeintrag
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    	switch (item.getItemId()) {
    	// Ergebnisliste löschen
		case R.id.optLoeschen:
			TextView ergebnisse = (TextView)findViewById(R.id.txtErgebnisse);
			ergebnisse.setText("");

			break;

		// Programm schließen
		case R.id.optSchliessen:
			this.finish();

			break;

		default:
			break;
		}
    	return true;
    }

    /**
     * Initialisierung der Oberfläche
     */
    private void Init(){
    	// Button mit einem Listener verbinden
    	Button cmdBerechnen = (Button)findViewById(R.id.cmdBerechnen);
    	cmdBerechnen.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				kursBerechnen();
			}
		});
    }

    /**
     * Berechnung und Ausgabe des Ergebnisses
     */
    private void kursBerechnen(){
    	// Elemente auslesen
    	EditText txtBetrag = (EditText)findViewById(R.id.txtBetrag);
    	TextView txtErgebnis = (TextView)findViewById(R.id.txtErgebnisse);
    	Spinner selWaehrungStart = (Spinner)findViewById(R.id.selWaehrungStart);
    	Spinner selWaehrungEnde = (Spinner)findViewById(R.id.selWaehrungEnde);

    	Boolean failure = false;

    	// Uwandlung des Betrages in eine Zahl
    	String betragText = txtBetrag.getText().toString();
    	Double betrag = 0d;
    	if (betragText != null && betragText != "") {
    		try {
    			betrag = Double.parseDouble(betragText);
			} catch (NumberFormatException e) {
				Toast.makeText(this, R.string.err_betarg_format, Toast.LENGTH_LONG).show();
				failure = true;
			}
		}

    	// Bestimmen der Ausgangs- und Zielwährung
    	int wahrungStart = selWaehrungStart.getSelectedItemPosition();
    	int waehrungEnde = selWaehrungEnde.getSelectedItemPosition();

    	// Bestimmen des jeweiligen Wechselkurses
    	String kursStartText = getResources().getStringArray(R.array.waehrung_kurs)[wahrungStart];
    	String kursEndeText = getResources().getStringArray(R.array.waehrung_kurs)[waehrungEnde];

    	// Umwandlung des Kurses in eine Zahl
    	Double kursStart = 0d;
    	Double kursEnde = 0d;
    	if (kursStartText != null && kursStartText != "" && !failure) {
			try {
				kursStart = Double.parseDouble(kursStartText);
			} catch (NumberFormatException e) {
				Toast.makeText(this, R.string.err_kurs_format, Toast.LENGTH_LONG).show();
				failure = true;
			}
		}
    	if (kursEndeText != null && kursEndeText != "" && !failure) {
			try {
				kursEnde = Double.parseDouble(kursEndeText);
			} catch (NumberFormatException e) {
				Toast.makeText(this, R.string.err_kurs_format, Toast.LENGTH_LONG).show();
				failure = true;
			}
		}

    	if(!failure){
	    	// Umrechnung
	    	Double ergebnis = betrag / kursStart * kursEnde;

	    	// Ergebnis ausgeben
	    	StringBuilder ergebnisText = new StringBuilder();
	    	ergebnisText.append(getResources().getStringArray(R.array.waehrung)[wahrungStart].subSequence(0, 3))
	    		.append(" ")
	    		.append(String.format("%.2f", betrag))
	    		.append(" = ")
	    		.append(getResources().getStringArray(R.array.waehrung)[waehrungEnde].substring(0, 3))
	    		.append(" ")
	    		.append(String.format("%.2f", ergebnis))
	    		.append("\n");
	    	txtErgebnis.setText(txtErgebnis.getText() + ergebnisText.toString());
    	}
    }
}

In der Zeile 21 wird durch den Aufruf der Methode setContentView(R.layout.main); wiesen wir unseren Activity HauptActivity.java ein Layout zu, den wir wieder über die generierte Klasse “R” ansprechen.

Der Aufruf unserer eigenen Methode Init() in der Zeile 23 setzt den Listener für unseren Berechnungs-Knopf. Nun wenden wir uns der eigentlichen Berechnung zu (Zeilen 75 bis 142).

Als Erstes holen wir uns die Referenzen zu allen Views, die wir für unsere Berechnung benötigen (Betrag, Ausgangswährung, Endwährung und Ergebnisfeld).

In der Zeile 87 erhalten wir durch den Aufruf der Methode getText() den Betrag für die Umrechnung. Das ist allerdings ein Textfeld und wir benötigen eine Zahl. Aus diesem Grund konvertieren wir den erhaltenen Text in ein Double-Format (mit der vorherigen Prüfung, ob der Text überhaupt eingegeben wurde, Zeile 89).

In den Zeilen 99 und 100 erhalten wir den Index des ausgewählten Eintrages aus den Auswahlboxen der Währung. Jetzt kommt uns der zweite Array, in dem wir die Kurse definiert haben, zugute. Dieser ist genauso von der Reihenfolge her aufgebaut, wie das Währungs-Array. Nun können wir durch den Index aus den Zeilen 99 und 100 die Kurse ermitteln (Zeilen 103 und 104). Diese sind wiederum Texte und müssen zuerst in Double konvertiert werden, wie bereit beim Betrag.

Wenn alle Konvertierungen ohne Fehler durchgelaufen sind, berechnen wir nun in der Zeile 128 den umgerechneten Betrag. Um eine schöne Anzeige zu erhalten, formatieren wir nur ein wenig unsere Ausgabe. Die Anzeige soll dann in etwa folgendermassen aussehen:

EUR 125,00 = USD 172,44

Damit wir auch eine Geschichte unserer Berechnungen erhalten, hängen wir in der Zeile 140 unser Ergebnis an den vorhandenen Text an.

Um dem Benutzer zu signalisieren, dass mit der Berechnung etwas schief gelaufen ist, erzeugen wir bei einem Konvertierungsfehler einen Toast (kleine Benachrichtigung, die kurz auf dem Bildschirm erscheint). Das erfolgt in den Zeilen 93, 113 und 121. Wenn Sie einen solchen Fehler provozieren wollen, tauschen Sie einfach in der array.xml-Datei in dem Werte-Array die Punkte durch die Kommas aus (erzeugt Fehler beim Konvertieren).

Lokalisierung

Die Lokalisierung ist unter Android relativ einfach gelöst. Die Ressourcen, die keinen Länder-Postfox haben, gehören zu der Standardsprache (in unseren Fall Deutsch). Die Standardsprache muss immer vollständig sein. Weitere Sprachen dagegen nicht. Wird eine spezielle Übersetzung nicht gefunden, wird die der Standard-Übersetzung genommen.

In unserer App müssen die Daten aus der strings.xml und arrays.xml Dateien übersetzt werden. Dafür klicken Sie mit der rechten Maustaste auf das Projekt und wählen Sie Android Tools -> New Ressource File... . Wie im Bild zu sehen ist, muss für neue Sprache nun unter “Available Qualifiers” “Language” auswählen und auf der rechten Seite den zweistelligen Ländercode eingeben (“en” für Englisch). Nun kann der Inhalt der beiden Dateien in die neuen kopiert werden und die Werte übersetzt werden. Die neuen Dateien landen im Ordner “res/values-en“.

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
	<!-- Globale Strings -->
	<string name="app_name">Currency Calculator</string>

	<!-- View Texte -->
    <string name="betrag_eingeben">Please type the value to calculate!</string>
    <string name="cmd_berechnen">Calculate</string>

    <!-- Menü -->
    <string name="opt_loeschen">Clear Result List</string>
    <string name="opt_loeschen_kurz">Clear</string>
    <string name="opt_schliessen">Close App</string>
    <string name="opt_schliessen_kurz">Close</string>

    <!-- Fehlertexte -->
    <string name="err_betarg_format">The value has wrong format!</string>
    <string name="err_kurs_format">The currency value has wrong format!</string>
</resources>

arrays.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="waehrung">
        <item>EUR - Euro</item>
        <item>USD - American Dollar</item>
        <item>AUD - Australian Dollar</item>
        <item>RUB - Russian Rubel</item>
        <item>CUD - Canadian Dollar</item>
        <item>GBP - Great Britain Pound</item>
    </string-array>
</resources>

Menü

Nun gehen wir an das Menü. Dafür erstellen wir wieder eine neue Android Ressource-Datei von Typ Menü. Diese XML-Datei landet im Ordner “res/menu“.

menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu
  xmlns:android="http://schemas.android.com/apk/res/android">
    <item
    	android:title="@string/opt_loeschen"
    	android:titleCondensed="@string/opt_loeschen_kurz"
    	android:id="@+id/optLoeschen"
    	android:icon="@drawable/opt_clear" />
    <item
    	android:title="@string/opt_schliessen"
    	android:titleCondensed="@string/opt_schliessen_kurz"
    	android:id="@+id/optSchliessen"
    	android:icon="@drawable/opt_close" />
</menu>

In unseren Activity-Java-Datei müssen nur noch wenige Zeilen hinzugefügt werden, um dem Menü ein Leben einzuhauchen. In den Zeilen 30 bis 34 wir das Menü initialisiert (ähnlich, wie das Layout in der onCreate-Methode). Dafür dient die überschriebene Methode onCreateOptionsMenu(). Unter Optionsmenü versteht man unter Android das Menü, das durch das Betätigen der Menütaste erscheint.

Die Auswertung, welches der Menüpunkte nun ausgewählt wurde, erfolgt in der überschriebenen Methode onOptionsItemSelected(). Über die Item-ID können wir bestimmen, was nun ausgewählt wurde und abhängig davon unseren Code ausführen (hier ist ein CASE-Konstrukt sehr gut geeignet, um die Menüpunkte zu unterscheiden und den Code übersichtlich zu halten). Für das Schließen unseren App benötigen wir nur eine Zeile mit this.finish() (Zeile 51). Um die Ergebnisse zurückzusetzen, müssen wir wieder die Referenz auf das View holen und deren Text auf einen leeren Text setzen (Zeilen 44 und 45).

Damit ist unsere App so weit funktionsfähig und einsatzbereit. Die Kurse können sehr einfach in der XML-Datei angepasst und erweitert werden.

Zum Original Blog
Autor: WebDucer

Android: Erste App (Währungsrechner) – Teil 1


Android: Erste App (Währungsrechner) – Teil 1
Zum Original Blog WebDucer techBlog

Dieser Beitrag zeigt an einer sehr einfach gehaltenen App, wie man seine erste App für Android erstellen kann. Dabei werden die benötigten Elemente und Schritte detailliert beschrieben und bebildert. Das fertige Projekt kann unter dem unten stehenden Link von GitHub heruntergeladen (oder geklont) werden.

GitHub Projekt-Repository

Projektbeschreibung (Zielsetzung)

In diesem Beitrag wird ein einfacher Währungsrechner erstellt. Folgende Aufgaben / Voraussetzungen muss die fertige App erfüllen:

  • Eingabe eines Betrages zum Umrechnen
  • Validierung der Eingaben (nur Zahlen)
    • Auswahl der Ausgangs- und Zielwährung
  • Berechnung des Betrages in der Zielwährung
  • Ausgabe der Berechnung
    • Die letzen Ergebnisse in einer Liste ausgeben
  • Löschen der Ergebnisliste über ein Menü
  • Beenden der App über ein Menü
  • Mehrsprachigkeit

Durch diese relativ einfache Anwendung werden die unter Android am meisten benutzte Elemente vorgestellt.

Anlegen des Projektes unter Eclipse

Eine genaue Beschreibung, wie Sie Eclipse auf Ihrem System einrichten, finden Sie unter “Android: Eclipse installieren und einrichten“. Im Beitrag “Android: Neues Projekt anlegen” finden Sie die Beschreibung, wie Sie ein neues Android-Projekt mithilfe des Assistenten unter Eclipse anlegen. Für das folgende Projekt sollten Sie die folgenden Werte beim Anlegen des Projektes angeben, um den Beschreibungen und Code-Ausschnitten besser folgen zu können:

  • Project name: Waehrungsrechner
  • Contents: Create new project in workspace
  • Build target: Android 2.2 (API Level 8 )
  • Application name: Waehrungsrechner
  • Package name: de.webducer.android.wrechner
  • Create Activity (angehackt): HauptActivity
  • Min SDK Version: 8

Nach der Neuanlage des Projektes wird der erste Bildschirm bereits mit einem Element, dass den Text “Hallo World” enthält. Nun können Sie das Projekt zum ersten Mal starten. Dafür gehen Sie wie folgt vor:

  1. Markieren Sie im “Package Explorer” das Projekt
  2. Klicken Sie mit der rechten Maustaste darauf und
  3. wählen Sie im Kontextmenü den Punkt “Run as” -> “Android Application”

Nach einiger Zeit startet zuerst der eingerichtete Emulator (das kann abhängig vom Rechner auch einige Minuten dauern). Danach startet im Emulator das Programm. Schließen den Emulator nicht, dann wird die neue Version sehr schnell auch auf dem Emulator angezeigt.

Aber nun der Reihe nach. Zuerst erkläre ich die Datei-Struktur von unserem Projekt.

Ordner und Dateistruktur des Projektes

Projektstruktur

Projektstruktur

src
In diesem Verzeichnis liegen die Quellcode-Dateien zu Ihrer App (Java-Dateien). Im Moment sollte in diesem Ordner nur die Datei “HauptActivity.java” liegen (im entsprechenden Package “de.webducer.android.wrechner”).
gen
Das ist ein automatisch generiertes Verzeichnis von Android. Die automatisch generierte Klasse “R” beinhaltet die Verweise auf die Ressourcen-Variablen und dient zum Zugriff auf diese aus dem Quellcode heraus. Zu den Ressourcen gehören unter anderen die übersetzbaren Strings, Layouts, Farben, Arrays, Bilder usw.
Android 2.2
In diesem Ordner ist die Android-Bibliothek abgelegt. Abhängig von der ausgewählten Android-SDK-Version wird eine andere Nummer angezeigt.
assets
In diesem Ordner werden Ressourcen abgelegt, die nicht über den Ressourcen-Manager verwaltet werden und in Unterverzeichnisse gegliedert werden können.
res
In diesem Ordner werden Ressourcen abgelegt, die über den Android-Ressource-Manager zur Verfügung gestellt werden und in der R.-Klasse abgebildet werden. Die einzelnen Unterordner werden weiter unten beschrieben.
drawable-XX
In diesen Ordnern werden die Bilder für die App gespeichert. XX steht dabei für eine bestimmte Ausflösungsdichte und wird dynamisch abhängig vom Auflösungsvermögen des Zielbildschirms ausgelesen.
layout
In diesem Ordner liegen die Layout-Definitionen für unsere App. In unserem Fall sollte am Anfang nur die Datei “main.xml” vorliegen.
values
In diesem Ordner werden unterschiedliche Werttypen gespeichert. Unter anderem sind hier die Strings-Definitionen für die Mehrsprachigkeit einer App definiert. Weitere Wertgruppen sind zum Beispiel Farben, Designs, Arrays usw.
AndroidManifest.xml
Diese Datei definiert unsere App und regelt unter anderem auch die notwendigen Berechtigungen.

Das Layout

Währungsrechner-Layout

Währungsrechner-Layout

Unser Layout für die App besteht aus folgenden Elementen (Widgets):

  • EditText: Für die Eingabe des Betrages für die Umrechnung
  • Spinner: Zwei Auswahlboxen für die Auswahl der Ausgangs- und der Zielwährung
  • Button: Knopf, um die Umrechnung anzustoßen
  • TextView: Bereich, in dem die Ergebnisse angezeigt werden (zusammen mit älteren Umrechnungen)

main.xml

<?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"
    >
    <EditText
    	android:layout_height="wrap_content"
    	android:id="@+id/txtBetrag"
    	android:layout_width="fill_parent"
    	android:hint="@string/betrag_eingeben"
    	android:inputType="numberDecimal">
    </EditText>
    <LinearLayout
    	android:orientation="horizontal"
    	android:weightSum="3"
    	android:layout_height="wrap_content"
    	android:layout_width="fill_parent">
	    <Spinner
	    	android:layout_height="wrap_content"
	    	android:layout_width="0dp"
	    	android:layout_weight="1"
	    	android:id="@+id/selWaehrungStart">
	    </Spinner>
	    <Spinner
	    	android:layout_height="wrap_content"
	    	android:layout_width="0dp"
	    	android:layout_weight="1"
	    	android:id="@+id/selWaehrungEnde">
	    </Spinner>
	    <Button
	    	android:text="@string/cmd_berechnen"
	    	android:id="@+id/cmdBerechnen"
	    	android:layout_width="0dp"
	    	android:layout_weight="1"
	    	android:layout_height="wrap_content">
	    </Button>
	</LinearLayout>
	<ScrollView
		android:layout_height="fill_parent"
		android:layout_width="fill_parent">
	    <TextView
	    	android:id="@+id/txtErgebnisse"
	    	android:layout_width="fill_parent"
	    	android:layout_height="fill_parent"
	    	android:gravity="top">
	    </TextView>
	</ScrollView>
</LinearLayout>

Ein Android-Layout besteht aus einfachen Views (wie EditText, Button usw.) und den sogenannten View-Gruppen-Elementen, die weitere Elemente enthalten dürfen. Das oberste Element ist immer eine View-Gruppe. In unserem Fall ist es ein LinearLayour. Diese Gruppe richtet die enthaltenen Elemente abhängig von der Orientierung neben- (horizontal) oder übereinander (vertical) an (Zeilen 4 und 17). Das Linear-Layout Element aus der Zeile 2 ordnen somit alle enthaltenen Elemente untereinander. Und das Linear-Layout aus Zeile 15 ordnet die 3 enthaltenen Elemente nebeneinander.

Die Angabe in allen Views android:layout_width bestimmt die Bereite des Elementes, android:layout_height die Höhe. Es sind folgende Werte möglich:

  • fill_parent (oder match_parent): View nimmt die gesamte Breite / Höhe ein, die das Elternelement zur Verfügung stellt.
  • wrap_content: View nimmt die Breite / Höhe des eigenen Inhaltes ein.
  • Wert in Pixel (px) oder Device Independent Pixel (dp / dip).

Somit nimmt unser LinearLayout aus Zeile 2 die gesamte Breite und Höhe (ganzer Bildschirm), das EditText dagegen zwar die gesamte Breite, aber nur eigene Höhe ein.

In der Zeile 10 sehen wir ein spezielles Konstrukt (android:id="@+id/txtBetrag"). Mit dieser Angabe “@+id/” teilen wir dem Compiler mit, dass dieses Element eine eindeutige ID erhalten soll, gefolgt von dem Namen, den wir frei vergeben können. Über diese ID können wir später auf das View aus dem Quellcode zugreifen (R.id.txtBetrag).

In der Zeile 12 (android:hint="@string/betrag_eingeben") kommt wieder ein spezieller Android-Konstrukt. Über die Angabe “@string/” können wir auf die String-Ressourcen aus dem “res“-Ordner zugreifen. Das sind die übersetzten Text-Platzhalter. Die string.xml folgt weiter unten. Die Angabe android:hint legt einen Hinweistext fest, der nach der Eingabe der ersten Zahlen verschwindet.

Die Angabe in der Zeile 13 (android:inputType="numberDecimal") legen wir fest, dass im Eingabefeld nur positive Zahlen eingegeben werden dürfen.

Damit wir die 3 Views nebeneinander und in der gleichen Breite darstellen, nutzen wir statt der absoluten Breitenangabe (z.B. Zeile 22 android:layout_width="0dp") eine relative Angabe zum Eleternelemet. LinearLayout aus Zeile 15 definiert, dass den Kindelementen eine Gewichtungssumme von 3 zur Verfügung gestellt wird (Zeile 17 android:weightSum="3"). Die 3 Views haben jeweils eine Gewichtung von 1 (Zeile 23 android:layout_weight="1"), also genau 1/3 der Gesamtgewichtung.

In der Zeile 40 ist das TextView innerhalb eines ScrollView (View-Gruppe) platziert. Das erlaubt uns später durch die Ergebnisse zu scrollen, falls es mehr sein werden, als der Platz auf dem Bildschirm erlaubt.

Mit der Zeile 47 (android:gravity="top") geben wir an, dass der Text oben (im Bezug zum Elternelement) platziert werden soll.

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="betrag_eingeben">Bitte den Betrag hier eingeben!</string>
    <string name="app_name">Währungsrechner</string>
    <string name="cmd_berechnen">Berechnen</string>
</resources>

Android: Erste App (Währungsrechner) – Teil 2

Zum Original Blog
Autor: WebDucer

Android: Neues Projekt anlegen

Backlinkseller

Android: Neues Projekt anlegen
Zum Original Blog WebDucer techBlog

Der erste Schritt zu der eigenen App ist ein neuer Android Projekt. Dieser Beitrag zeigt, wie dies unter Eclipse zu erledigen ist.

New Android Project
Project Wizzard 1
Project Wizzard 2
Project Wizzard 3

Neues Android-Projekt wird über das Menü „File“ → „New“ → „Android Project“ angelegt (siehe Bild). Sollte dieser Menüpunkt nicht sichtbar sein, gehen Sie auf „Others“ und wählen Sie dann im folgenden Dialog „Android Project“.

Im folgenden Assistenten müssen folgende Angaben gemacht werden (siehe Bilder):

  • Project name: Projektname ohne Sonderzeichen (z.B.: MeineApp)
  • Build Target: Compiler-Version, mit der die App kompiliert wird (z.B.: 8 für Android 2.2 Geräte)
  • Application name: Bezeichnung der App, so wie diese im Menü des Smartphones erscheinen soll (z.B.: Meine Erste App)
  • Package name: Hierarchische Bezeichnung des Java-Packages. Oft als umgekehrte URL angegeben (z.B.:  de.meinedomein.appname)
  • Min SDK version: minimale Anforderungen an das Gerät (z.B.: 4 für Android 1.6)

Für komplexere Apps ist es empfehlenswert zur App auch TestUnits zu schreiben, um bei neueren Versionen die Funktionalität automatisiert testen zu können. Das kann im nachfolgenden Dialog mit erledigt (siehe Bild) oder später dem Projekt hinzugefügt werden.

Zum Original Blog
Autor: WebDucer

Android: Eclipse installieren und einrichten

Android: Eclipse installieren und einrichten
Zum Original Blog WebDucer techBlog

Für die Android-Programmierung bietet sich sehr gut die Entwicklungsumgebung Eclipse mit den Android Development Tools von Google an. In diesem Beitrag beschreibe ich die Installation von beiden, um mit der Android-Programmierung anschließend sofort loslegen zu können.

Install New Software
ADT
ADT URL
Preferences
Android SDK Download
AVD Device

Installation von Eclipse

  1. Eclipse Classic ab Version 3.5 herunterladen (www.eclipse.org/downloads/).
  2. Die heruntergeladene Datei in einen Ordner entpacken (z.B.: C:\Entwicklung\Eclipse unter Windows, oder /Users/Shared/Entwicklung/Eclipse unter Mac OS X).
  3. Eclipse starten und das Standard-Workplace (z.B.: C:\Entwicklung\Android unter Windows oder /Users/Shared/Entwicklung/Android unter Mac OS X) vergeben.

Installation von Android Development Tools (ADT)

  1. Android SDK für das gewünschte Betriebssystem herunterladen (http://developer.android.com/sdk/index.html).
  2. Die heruntergeladene Datei in einen Ordner entpacken (z.B.: C:\Entwicklung\AndroidSDK unter Windows oder /Users/Shared/Entwicklung/AndroidSDK unter Mac OS X).
  3. Eclipse starten und zu Help → Install New Software gehen.
  4. Bei „Work with:“ auf „Add...“ klicken, um neues Software-Repository hinzuzufügen (siehe Bild).
  5. Namen frei vergeben und als „Location“ https://dl-ssl.google.com/android/eclipse/ eingeben.
  6. OK klicken.
  7. Developer Tools als zu installierende Komponenten auswählen (es dauert einige Zeit, bis die Repository eingelesen wird).
  8. Die Installation mit „Next“ → „Next“ → „Accept“ und „Finish“ abschließen.
  9. Eclipse neu starten.
  10. Gehen Sie zu Preferences (unter Winsdows über Window → Preferences, unter Mac OS X über Eclipse → Prefenrences zu erreichen.
  11. Gehen Sie zum Punkt „Android“ und tragen Sie da den Speicherort von Android-SDK ein (nach dem Vorschlag wäre es unter Windows der Ordner C:\Entwicklung\AndroidSDK und unter Mac OS X /Users/Shared/Entwicklung/AndroidSDK).
  12. Nun gehen Sie zu „Window“ → „Android-SDK Manager“ und installieren Sie die benötigten (z.B.: Android 1.6 und Android 2.2) oder alle SDK-Versionen.
  13. Nach dem Neustart von Eclipse gehen Sie wieder zu „Window“ → „AVD Manager“.
  14. Legen Sie mit „New“ die virtuellen Android-Geräte, für die Sie entwickeln möchten (z.B.: ein Android 2.2 Gerät mit WXGA Auflösung [800x480] und 2GB SD-Karte). Sie können auch mehrere virtuelle Geräte anlegen und beim Start eines Android-Projektes dann eins davon auswählen.
  15. Damit sind alle Vorbereitungen für die Android-Programmierung getroffen.

Update

  • 22. Januar 2012: Anpassungen an ADT Revision 16

Zum Original Blog
Autor: WebDucer

Erfahrungen mit Windows 7 auf einem Netbook (ASUS EeePC 1000H)

Erfahrungen mit Windows 7 auf einem Netbook (ASUS EeePC 1000H)
Zum Original Blog WebDucer techBlog

Nach über einem halben Jahr des Einsatzes von Windows 7 auf meinem EeePC kann ich nur eine positive Bilanz ziehen.

Installation

Vor der Windows 7 Installation sollte der ASUS Empfehlung nach, zuerst das aktuelle Update für BIOS installiert werden (momentan Version 2204).

Die Installation von Windows 7 auf einem Netbook gestaltet sich endlich sehr einfach und bedarf kein DVD-Laufwerk mehr, wie es bei XP oder Vista der Fall war. Microsoft liefert hierfür ein Tool namens “Windows 7 USB/DVD Download Tool“, mit dem eine ISO-Datei von Wndows 7 direkt auf ein USB-Stick transferiert und dieses bootbar gemacht wird. Das konnte ich auf dem damals noch installierten Windows XP auf dem Netbook ohne Weiteres durchführen. Das einzige Problem stellt sich wahrscheinlich für die meisten, das “Beschaffen” eines ISO-Abbildes von Windows 7. Diejenigen, die einen Vertrag mit Microsoft haben (z.B. Action Pack), können die ISO direkt herunterladen. Wenn man Windows 7 bei Microsoft und einigen Partnern in der digitalen Version bestellt, bekommt man auch ein ISO-Abbild zu Download angeboten. Alle anderen müssen, wohl oder übel, auf einem Rechner mit DVD-Laufwerk eine ISO-Datei von der Original-Windows 7 DVD erstellen (z.B. mit Nero oder InfraRecorder unter Windows oder Burn unter MacOS X).

Um vom USB-Stick zu installieren, muss beim ASUS EeePC 1000H beim Start des Netbooks die “ESC”-Taste gedrückt werden. Dann erscheint ein Menü zur Auswahl des Boot-Laufwerkes (Festplatte, SD-Karte, falls eingesteckt, externes DVD-Laufwerk, falls angeschlossen und USB-Stick). Die weitere Windows 7 Installation verläuft, als ob man Windows 7 von der DVD installieren würde.

Nach der Installation wurden die komplette Hardware ,ohne zusätzliche Treiber, direkt erkannt und das Netbook war soforteinsatzbereit. ASUS liefert aber auch direkt Windows 7 Treiber.

Windows 7 Vorteile gegenüber Windows XP

Aufwachen

Windows 7 scheint im Alltag flotter zu arbeiten, als Windows XP auf demselben Gerät es tat. Das gilt insbesondere für den von mir oft eingesetzten Bereitschaftsmodus (Suspend to RAM). Das Netbook wacht in der Regel (es gibt nur selten Ausnahmen) in weniger als 5 Sekunden auf. Bis ich mich neu eingeloggt habe (1-2 Sekunden), ist auch das WLAN wieder da. Unter Windows XP musste ich zum Teil über 15 Sekunden nach dem Anmelden auf eine neue Verbindung zum WLAN warten.

In über 6 Monaten Einsatz ist das Gerät kein einziges Mal abgestürzt. Und das Gerät läuft oft über eine Woche ohne Herunterfahren (nur Bereitschaft, wenn dieser mal nicht benötigt wird).

Akku

Der Akku hält erfreulicherweise genauso lange/kurz, wie auch unter Windows XP. Mit WLAN und ausgeschalteten Bluetooth hält dieser bei ständigem im Internet surfen und Last.fm hören ca. 3,5 Stunden durch. Die theoretischen 7 Stunden hielt das Netbook auch unter Windows XP nie durch. Am Anfang waren es knapp 5,5 – 6 Stunden, dann pendelte sich der Akku aber auf ca. 3,5 – 4 Stunden.

Internet

Im Internet bin ich mit Firefox und Opera unterwegs. Es unterstützen aber mittlerweile alle Browser. Es geht um den Vollbild-Modus. Bei IE, Firefox, Opera, Chrome wechselt man zu und von diesem Modus durch Drücken der “F11″-Taste. Mittlerweile surfe ich nur in diesem Modus.

Bei Chrome und Opera muss man leider den Vollbild-Modus verlassen, um eine neue Adresse einzugeben. Bei Firefox und IE reicht es mit der Maus nach oben zu gehen. Dann erscheint die Adressleiste und man kann die neue Adresse eingeben.

Windows 7 Einschränkungen

Arbeitsspeicher

Den 1GB RAM merkt man bei Windows 7 eher schneller als unter Windows XP. Wenn man Firefox mit 3-4 Tabs startet (ca. 250MB verbrauch), dazu noch OpenOffice auf hat (ca. 150MB) und iTunes startet, ist Schluss mit lustig. RAM ist voll und es macht kein Spaß mehr mit dem Gerät zu arbeiten. Meine nächste Anschaffung werden wohl 2GB RAM für mein Netbook sein :-)

Auflösung

Eine weitere, ab und zu sehr hinderlicher, Einschränkung ist die Auflösung. Unter Windows XP konnte man die Auflösung auch höher drehen, als das Bildschirm es eigentlich könnte (1024×768). Das geht mit den ASUS Treibern leider nicht mehr. Man kann zwar auf 800×600 herunter schalten, aber nicht höher, als die native Auflösung des Netbooks. Bei Programmen, die eine Auflösung von mehr als 1024×600 verlangen gibt es dann nur zwei Auswege:

  1. Anschließen eines externen Bildschirms, das eine höhere Auflösung hat,
  2. oder Installation eines alternativen Grafiktreibers (findet man in einigen EeePC Foren).

Ich habe mich für die erste Variante entschieden, da ich erstens nicht so viele Programme habe, die das verlangen, und zweitens ich bereits einen externen Bildschirm habe, denn ich dafür einsetzen kann.

Als weitere Maßnahme habe ich die Startleiste recht angeordnet, sodass mir die 600 Pixel Höhe auch wirklich zur Verfügung stehen.

Langsames Aufwachen

Es passiert sehr selten, aber ab und zu schon, dass das Netbook über 30 Sekunden zum Aufwachen braucht. Dann ist dieser aber ganz normal weiter benutzbar. In den über 6 Monaten täglichen Einsatzes passierte es noch kein einziges Mal, dass das Netbook gar nicht mehr aufwachte oder mit einem Blue Screen sich verabschiedete.

Nur wenn man das RAM ausreizt und das Betriebssystem zum Cachen auf die Festplatte gezwungen wird, ist es ab und zu schneller den Rechner hart auszuschalten (langes Drücken auf den Ausschaltknopf) und neu zu starten, als zu warten, bis die notwendigen Befehle (Programme beenden und Neustarten) vom Betriebssystem umgesetzt werden. Mit der Zeit kennt man aber die Grenzen des 1GB sehr gut und vermeidet solche “Ausrutscher”.

Treiber

ASUS schein momentan noch Probleme mit zumindest einem Treiber zu haben. Nach der Installation von “ASUS Instant Key Utility” wird bei mir beim Start von Windows immer die Meldung gezeigt, dass der Touchpad Treiber nicht gefunden werden kann. Es sind allerdings alle bei ASUS verfügbare (auch für den Touchpad) Treiber installiert. Entweder ist hier das Utility, oder der Treiber defekt. Und es ist kein Update in Sicht.

Fazit

Im Ganzen bin ich sehr mit Windows 7 auf meinem Netbook zufrieden. 2GB RAM sind zwar zu empfehlen, man kann aber auch mit 1GB RAM relativ gut damit arbeiten, wenn man ein paar Vorsichtsmaßnahmen trifft (nur wenige Programme parallel laufen lassen).

Wer eine freie Windows 7 Lizenz noch hat, würde ich zum Umstieg von Windows XP auf Windows 7 raten, besonders da die Installation mittlerweile ohne Probleme auch von einem USB-Stick klappt.

Zum Original Blog
Autor: WebDucer

Mehrere gleichnamige Zertifikate unter Thunderbird nutzen

Mehrere gleichnamige Zertifikate unter Thunderbird nutzen
Zum Original Blog WebDucer techBlog

Zertifikatübersicht

Zertifikatübersicht

Heute bin ich mit einem Problem gestoßen. Ich habe mir für meine zwei Haupt-Email-Adressen Zertifikate bei trustcenter.de bestellt.  Naturgemäß lauten beide auf meinen Namen. Theoretisch sollte es damit auch keine Probleme geben, da beide ja auf unterschiedliche Email-Adressen ausgestellt sind.

Auf dem Mac unter Mail gab es auch keine Probleme. Beide Zertifikate wurden problemlos importiert und konnten zum Signieren und Verschlüsseln benutzt werden.

Problem

Zertifikatzuordnung

Zertifikatzuordnung

Auf dem EeePC bin ich vor Kurzem von Windows Live-Mail auf Thunderbird 3.0 umgestiegen. Der Import verlief auch ohne Probleme und es wurden beide Zertifikate in der Übersicht angezeigt. Das Problem taucht auf, wenn man versucht die Zertifikate den einzelnen Email-Adressen zuzuweisen. In der Drop-Down-Liste erscheint nur ein einziges Zertifikat statt der beiden importierten.

Einzeln importiert funktionieren diese problemlos. Zusammen importiert, wird nur ein Zertifikat angezeigt.

Nach langer Recherche konnte die Ursache in der Bildung der Drop-Down-Liste von Thunderbird festgestellt werden. Zur Bildung der Liste werden bei Thunderbird nur Vor- und Nachnahme benutzt (CN), aber nicht die erweiterten Felder des Zertifikates. Viele andere Zertifikathersteller schreiben in die CN noch weitere Daten, sodass das beschriebene Problem meines Wissens nur bei trustcenter.de auftritt. Die Auszeichnung, wie trustcenter.de dies tut, entsprich der Empfehlung des Zertifikatstandards.

Lösung

Allgeminer Name

Allgeminer Name

Um das Problem bei Thunderbird und trustcenter.de zu umschiffen, habe ich eins von meinen Zertifikaten gesperrt und ein neues beantragt. Dieses Mal aber in dem Feld Vorname nicht nur meinen Vornamen eingegeben, sondern “Herr …”.

Nach dem neuen Import hat Thunderbird nun beide Zertifikate richtig aufgelistet und ich konnte diese den jeweiligen Email-Adressen zuordnen.

Alternativer Name

Alternativer Name

Zum Original Blog
Autor: WebDucer

Umstellung des Benutzerverzeichnisses “/Users” auf eine andere Partition unter Mac OS X

Umstellung des Benutzerverzeichnisses “/Users” auf eine andere Partition unter Mac OS X
Zum Original Blog WebDucer techBlog

Es gibt mehrere Möglichkeiten diese Aufgabe zu lösen. Ich stelle hier zwei Wege, wie man entweder das Benutzer-Verzeichnis eines Benutzers verschiebt, oder den kompletten Benutzer-Ordner umlenkt (gilt auch für allen danach neu angelegte Benutzer).

1. Benutzer-Verzeichnis eines Benutzers verschieben.

Systemeinstellungen -> Benutzer

Bild 1: Systemeinstellungen: Benutzer

Melden Sie sich am besten als ein anderer Benutzer, als der, den Sie “umziehen” möchten.

Öffne Sie die Systemeinstellungen und gehen Sie auf das Punkt Benutzer (siehe Bild 1). Unter Benutzer schalten Sie zuerst die Änderungsfunktion frei (das geschlossene Schloss unten links anklicken und mit Administratorrechten freigeben). Nun können Sie unter den Benutzer auswählen, dessen Benutzerordner Sie verschieben möchten. Klicken Sie auf diesen mit der rechten Maustaste (Kontextmenü) oder “Ctrl +  linke Maustaste”. Im Kontextmenü den Punkt “Erweiterte Optionen” auswählen. Es gibt ja nur diesen Kontextmenü-Eintrag :-) (siehe Bild 2).

Erweiterte Optionen

Bild 2: Erweiterte Optionen

Im neuen Unterfenster kann unter anderem auch der Benutzerordner neu festgelegt werden (siehe Bild 3).

Ordner ändern

Bild 3: Ordner ändern

Der Zielordner muss auf dabei bereits vorhanden sein.

Diese Methode hat einen entscheidenden Nachteil. Für jeden neu angelegten Benutzer muss die Prozedur wiederholt werden. Das ist zwar im häuslichen Bereich bei 2-3 Benutzern vertretbar, bei mehr Benutzern empfehle ich aber die zweite Methode: “Umlenken des gesamten /Users Ordners”.

2. Umlenken des gesamten /Users Ordners

Für diese Methode müssen wir uns des Terminals bemühen, da die Umlenkung des /User-Ordners durch einen so genannten symbolischen Link geschehen wird.

Als Erstes meldet man sich als Administrator an. Nach der Anmeldung sollten keine Programme im Hintergrund laufen (Mail usw.), da sonst das Löschen nicht richtig funktioniert (/Users wird sofort wieder neu angelegt). Das einzige Programm, das laufen soll, ist ein Terminalfenster.

Im zweiten Schritt wird das /Users-Verzeichnis auf die Zielpartition kopiert. Entweder über das Terminal oder auch mit dem Finder.

# sudo cp -Rp /Users /Volumes/NeuePartition/Users

Als Nächstes muss das “alte” /Users-Verzeichnis gelöscht werden. Das erledigt man auch am besten im Terminal-Fenster.

# sudo rm -R /Users

Im letzten Schritt legt man das Symbolische Link an, damit das Verzeichnis /Users auf den Ordner auf der anderen Partition zeigt.

# sudo ln -s /Volumes/NeuePartition/Users/ /Users

Jetzt nur noch abmelden und neu anmelden. Alle Benutzer liegen nun auch der anderen Partition, auch neu angelegte.

Wer auf Nummer sicher gehen will, sollte diese Operationen entweder von einer Installation auf einer externen HDD starten oder von der Boot-DVD (Terminalfenster aufrufen, bevor die Installation anfängt). Dann sägt man sprichwörtlich nicht an dem Ast, auf dem man gerade sitzt.

In diesem Fall muss /Users durch /Volumes/SystempartitionName/Users ersetzt werden.

Auf demselben Weg kann auf Wunsch auch das Programm-Verzeichnis auf eine andere Partition “verschoben” werden.

Nach der Neuinstallation des Systems muss man nur den symbolischen Link neu setzten und alle Benutzer (incl. aller deren Einstellungen) sind wieder da.

Ich hoffe dieser Beitrag hat einigen geholfen, das Mac OS X noch ein wenig komfortabler zu machen.

WARNUNG: Das Arbeiten im Terminal mit administrativen Rechten erfolgt auf eigene Gefahr. Jeder, der sich auch das Terminal begibt, sollte wissen, was er mit dem System mach, da es hier keinen doppelten Boden und keine Sicherheitsabfragen gibt. Ein SuperUser darf eben ALLES machen, ohne Nachfragen.

Zum Original Blog
Autor: WebDucer

Update von Windows XP auf SP3 unter Snow Leopard (Bootcamp 3.0)

Update von Windows XP auf SP3 unter Snow Leopard (Bootcamp 3.0)
Zum Original Blog WebDucer techBlog

Die Neuerung, die Snow Leopard in Verbindung mit Bootcamp mit sich bringt, ist dass man nun auf die OS X Laufwerke unter Windows lesend zugreifen kann. Dieses an sich sehr schönes Feature bringt aber zugleich auch Probleme bei einer Neuinstallation von Windows XP (< SP3). Wenn man versucht SP3 nach der Installation der Treiber zu installieren, sieht Windows auch die Mac-Partitionen, die richtigerweise vor der Windows-Partition sitzen. SP3 versucht aber auf die erste Partition einige Dateien zu schreiben. Diese ist aber Mac OS X Systempartition, auf die Windows nur Schreibzugriff hat. Die Installation bricht immer wieder ab.

Die Lösung liegt darin, das Feature, die Mac-Partitionen zu sehen, temporär auszuschalten. Dazu muss im Ordner:

c:\Windows\System32\Drivers

In diesem Ordner muss die Datei AppleMNT.sys umbenannt werden. Nach dem Neustrat von Windows, werden die Mac-Partitionen nicht mehr erkannt und man kann den SP3 wie gewohnt installieren. Nach der Installation kann die Datei AppleMNT wieder zurück umbenannt werden.

Die Problematik ist auch bei Apple Support gut erklärt.

Zum Original Blog
Autor: WebDucer