<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Schlingels Werkstatt</title>
	<atom:link href="http://schlingel.bplaced.net/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://schlingel.bplaced.net</link>
	<description>Engineer your world, structure your environment</description>
	<lastBuildDate>Sun, 13 May 2012 07:40:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Der Abwärtstrend der deutschen Sprache</title>
		<link>http://schlingel.bplaced.net/?p=102</link>
		<comments>http://schlingel.bplaced.net/?p=102#comments</comments>
		<pubDate>Sat, 12 May 2012 20:43:22 +0000</pubDate>
		<dc:creator>schlingel</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[language]]></category>
		<category><![CDATA[text]]></category>

		<guid isPermaLink="false">http://schlingel.bplaced.net/?p=102</guid>
		<description><![CDATA[Wie macht man aus Text Bilder? Klar, man liest ihn doch wie macht man Bilder die man sich nicht nur mit dem geistigen Auge anschauen kann? Dazu habe ich ein sehr simples Programm geschrieben dass nichts anderes macht als einen &#8230;<p class="read-more"><a href="http://schlingel.bplaced.net/?p=102">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Wie macht man aus Text Bilder? Klar, man liest ihn doch wie macht man Bilder die man sich nicht nur mit dem geistigen Auge anschauen kann? Dazu habe ich ein sehr simples Programm geschrieben dass nichts anderes macht als einen vorliegenden Text als Anweisung zum zeichnen zu interpretieren.</p>
<p>Dazu macht mein kleines Programm nichts anderes als den Text in einen interpretierbaren Raum und ein paar Zeichen die abgeschnitten werden einzuteilen und dann den resultierenden Code als Anweisungen vorzunehmen. Die Anweisungen die der Interpreter versteht bestehen aus Quadrupeln. Ein Jedes Quadrupel besteht aus:</p>
<ol>
<li>Einer Richtung.</li>
<li>Dem Rotwert aus dem RGB-Raum</li>
<li>Dem Grünwert aus dem RGB-Raum</li>
<li>Dem Blauwert aus dem RGB-Raum</li>
</ol>
<p>Die einzelnen Werte werden sehr einfach ermittelt. Da Java auch Unicode versteht, wird der Modulo von 256 eines jeden Zeichens als Farbwert verwendet. Für die Richtung wird der Module von 4 des Eingabezeichens verwendet, wobei für ein kartesisches Koordinatenmodell gilt:</p>
<ul>
<li><strong>0:</strong> Es wird auf der Y-Achse nach oben gewandert.</li>
<li><strong>1:</strong> Es wird auf der X-Achse nach rechts gewandert.</li>
<li><strong>2:</strong> Es wird auf der Y-Achse nach unten gewandert.</li>
<li><strong>3:</strong> Es wird auf der X-Achse nach links gewandert.</li>
</ul>
<p>Das Ergebnis wird dann als PNG abgespeichert wobei das simple Testprogramm als Eingabe den Zielpfad erwartet. Bei der vorliegenden Konfiguration lässt sich aus allen getesteten Texten ein klarer Trend erkennen; der Graph sinkt. (x+, y-)</p>
<table>
<tbody>
<tr>
<td>Kleine Fabel, Kafka</td>
<td><a href="http://schlingel.bplaced.net/wp-content/uploads/2012/05/klfabel.png"><img class="aligncenter size-full wp-image-103" title="klfabel" src="http://schlingel.bplaced.net/wp-content/uploads/2012/05/klfabel.png" alt="" width="20" height="24" /></a></td>
</tr>
<tr>
<td>Text von Göthe</td>
<td><a href="http://schlingel.bplaced.net/wp-content/uploads/2012/05/goethe1.png"><img class="aligncenter size-full wp-image-105" title="goethe1" src="http://schlingel.bplaced.net/wp-content/uploads/2012/05/goethe1.png" alt="" width="1114" height="1214" /></a></td>
</tr>
<tr>
<td>Ausschnitt eines Edgar Wallace Romans (Deutsche Übersetzung)</td>
<td><a href="http://schlingel.bplaced.net/wp-content/uploads/2012/05/edwallace.png"><img class="aligncenter size-full wp-image-106" title="edwallace" src="http://schlingel.bplaced.net/wp-content/uploads/2012/05/edwallace.png" alt="" width="676" height="604" /></a></td>
</tr>
</tbody>
</table>
<p>Das ganze ist natürlich nur ein sehr primitiver Algorithmus aber trotzdem ganz witzig zum herumspielen und so wie die generierten Graphen aussehen wohl zu gebrauchen um einen Levelgenerator zu schreiben. Wer es selbst ausprobieren möchte findet hier das zugehörige <a href="http://schlingel.bplaced.net/wp-content/uploads/2012/05/TextToColorTest1.zip">Java-Projekt</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://schlingel.bplaced.net/?feed=rss2&amp;p=102</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fraktale &#8211; Einfach faszinierend</title>
		<link>http://schlingel.bplaced.net/?p=96</link>
		<comments>http://schlingel.bplaced.net/?p=96#comments</comments>
		<pubDate>Mon, 23 Apr 2012 18:05:39 +0000</pubDate>
		<dc:creator>schlingel</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Math]]></category>
		<category><![CDATA[Fraktale]]></category>

		<guid isPermaLink="false">http://schlingel.bplaced.net/?p=96</guid>
		<description><![CDATA[Man nehme ein bestehendes Viereck und setze an jede Ecke dieses Ursprungsviereckes ein neues Viereck. Das neue Viereck ist dabei genauso groß wie ein Viertel des ursprünglichen Vierecks. Diesen Vorgang wiederhole man so oft man möchte. Diese sehr einfache Vorschrift &#8230;<p class="read-more"><a href="http://schlingel.bplaced.net/?p=96">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Man nehme ein bestehendes Viereck und setze an jede Ecke dieses Ursprungsviereckes ein neues Viereck. Das neue Viereck ist dabei genauso groß wie ein Viertel des ursprünglichen Vierecks. Diesen Vorgang wiederhole man so oft man möchte.</p>
<p>Diese sehr einfache Vorschrift bringt schon erstaunliche Strukturen zu Tage wenn man sie nur sechsmal anwendet.</p>
<p><a href="http://schlingel.bplaced.net/wp-content/uploads/2012/04/Fraktale.png"><img class="aligncenter size-full wp-image-97" title="Fraktale" src="http://schlingel.bplaced.net/wp-content/uploads/2012/04/Fraktale.png" alt="A simple fractal generated" width="500" height="500" /></a>Zwar habe ich zur Zeit wieder viel mit Mathematik, vor allem Logik, im Studium zu tun doch muss ich zu geben, dass mich diese Anwendung nur peripher interessiert. Im Moment möchte ich mich mehr mit fraktaler Geometrie beschäftigen damit es mir möglich ist mehr als nur so simple Anwendungen um zu setzen</p>
<p>Wenn dennoch interessiert wie man obige Vorschrift imperativ umsetzt, kann sich gerne mein dazu gehöriges <a href="http://schlingel.bplaced.net/wp-content/uploads/2012/04/FirstFractal.zip">Java-Projekt</a> anschauen.</p>
]]></content:encoded>
			<wfw:commentRss>http://schlingel.bplaced.net/?feed=rss2&amp;p=96</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Architektur und Frameworks &#8211; Wo Domänenexperten Amateure unterbieten</title>
		<link>http://schlingel.bplaced.net/?p=89</link>
		<comments>http://schlingel.bplaced.net/?p=89#comments</comments>
		<pubDate>Sat, 07 Apr 2012 19:03:53 +0000</pubDate>
		<dc:creator>schlingel</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://schlingel.bplaced.net/?p=89</guid>
		<description><![CDATA[Ich denke ein jeder Programmierer kennt das Phänomen &#8211; wenn man erst einmal ein Framework gemeistert hat und sich vollends in die Entwicklung damit eingelebt habt, neigt man dazu die selben Designtechniken, Pattern und Klassenarchitektur auf andere Frameworks zu überführen. &#8230;<p class="read-more"><a href="http://schlingel.bplaced.net/?p=89">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Ich denke ein jeder Programmierer kennt das Phänomen &#8211; wenn man erst einmal ein Framework gemeistert hat und sich vollends in die Entwicklung damit eingelebt habt, neigt man dazu die selben Designtechniken, Pattern und Klassenarchitektur auf andere Frameworks zu überführen. Meistens damit, Code zu schreiben der für Vertraute des anderen Frameworks wie außerirdisch eingepflanzte Inseln wirken.</p>
<p>Warum schreibe ich über das Phänomen? Weil ich erst in einer <a href="http://www.java-forum.org/mobile-geraete/134328-ui-programmierung.html">Foren-Diskussion</a> lange aber ergebnislos damit beschäftigt war, einen Android-Anfänger davon zu überzeugen sich an die üblichen Techniken beim Android-Programmieren zu halten. Im speziellen wurden folgende Punkte als ekelhaft empfunden und gemieden:</p>
<ul>
<li>XML-Layouts</li>
<li>Das Adapter-Konzept bei ListViews</li>
<li>Aufteilen von komplexen Auswahlstrukturen auf mehrere Activities, da es der Komponentenstruktur zu wider laufe.</li>
</ul>
<p>Ich muss zugeben, ich kann die drei Abneigungen gut verstehen. Auf dem Desktop kam es mir zu Anfangs auch seltsam vor für die UI-Programmierung die Sprache zu wechseln. Mir ist nach wie vor WinForms sympathischer als WPF wenn es um C# geht. Und da ich mittlerweile nicht mehr als .Net-Entwickler arbeite, werde ich mir WPF/Silverlight wohl sparen. Für Windows 8 und Metro empfinde ich im Moment JS/HTML5 sowieso interessanter.</p>
<p>Doch in Android gehört es integral dazu. Alle Beispielprogramme von Android verwenden XML-Layouts. Der LayoutInflator wird überall verwendet wo es darum geht, dynamisch View-Elemente zu erstellen.</p>
<p>Manuell den Codebaum mit einem selbst erstellen View-Geflecht zu erweitern sieht man eher selten. Es wirkt auch sehr verkrampft und seltsam wenn plötzlich 20 Zeilen Code in einer Methode stehen, die das selbe leistet wie fünf Zeilen Code mit einer View die per XML erstellt wurde.</p>
<p>Der zweite Punkt war, die starke Fixierung darauf, dass die ListView auch Methoden zur Verfügung stellen solle um Elemente hinzuzufügen. Ich persönlich bin sehr schnell damit zu Rande gekommen, dass ich den Adapter dafür verwende und nicht die View selbst.</p>
<p>Wie der Name schon sagt, kam mir das auch sauberer vor. Immerhin wird so der Controller bzw. der Adapter und die View nicht vermischt. Die View sollte wirklich nicht mehr Aufgaben haben als Events an die jeweiligen Handler weiter zu leiten.</p>
<p>Doch der Punkt den ich am wenigsten nachvollziehen konnte, war die Forderung, dass der Code Komponenten abbilden solle. Davon abgesehen, dass es schwer ist abzugrenzen was eine Software-Komponente ist und was nicht, war es diese Ansicht, dass die View unbedingt alle nötige Logik kapseln müsse.</p>
<p>Das führt m.E. dazu, dass der Code sehr groß und schwer zu warten wird an den Stellen an dem das System etwas anderes erwartet. Ganz einfach weil man um die Gegebenheiten des Frameworks herum arbeiten muss.</p>
<p>Mein erstes Android-Projekt ging ich zu Anfangs auch ähnlich an. Ich wollte eine View-Komponente schreiben, die es dem Benutzer ermöglicht mehrere Bilder hintereinander hinzuzufügen.</p>
<p>Doch da pfuscht einem das System gleich mehrmals:</p>
<ul>
<li>Man benötigt Zugriff auf die Activity da man bei einem Image-Picker im onActivityResult darauf reagieren muss.</li>
<li>Das Auslagern von UI-Elementen in externe Libraries ist unangenehm gelöst. (R-Generierung etc.)</li>
</ul>
<p>Mein ursprüngliches Ziel konnte ich damals wegen den oben genannten Gründen nicht umsetzen. Denn immer wenn man beginnt gegen die vorgesehene Architektur zu kämpfen, sei es in dem man ein Monster-Menü in eine Klasse packt anstatt sie &#8211; wie es mobile UI Patterns empfehlen und Android entworfen wurde &#8211; auf mehrere Activities aufzuteilen, geht der Schmerz los.</p>
<p>Seit kurzem praktiziere ich Pain Driven Development, welches besagt die Architektur immer so simpel und angenehm wie möglich zu gestalten. Erst wenn der Schmerz losgeht, wird es geändert.</p>
<p>Damit fahre ich ganz gut und habe endlich angefangen meinen blinden YAGNI-Fleck abzulegen.</p>
]]></content:encoded>
			<wfw:commentRss>http://schlingel.bplaced.net/?feed=rss2&amp;p=89</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Na no na ned &#8211; HttpUrlConnection und Android target &gt;= 9</title>
		<link>http://schlingel.bplaced.net/?p=84</link>
		<comments>http://schlingel.bplaced.net/?p=84#comments</comments>
		<pubDate>Thu, 05 Apr 2012 08:46:34 +0000</pubDate>
		<dc:creator>schlingel</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Mobile]]></category>

		<guid isPermaLink="false">http://schlingel.bplaced.net/?p=84</guid>
		<description><![CDATA[Ich hab gerade eine Fehlersuche abgeschlossen die mich 4 verzweifelte Stunden meines Lebens gekostet hat. Das schlimme: eine winzige Kleinigkeit die sich nur für Android geändert hat, hat meiner App das Genick gebrochen. Nichts ging mehr &#8211; Nada, finito. Aber &#8230;<p class="read-more"><a href="http://schlingel.bplaced.net/?p=84">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Ich hab gerade eine Fehlersuche abgeschlossen die mich 4 verzweifelte Stunden meines Lebens gekostet hat. Das schlimme: eine winzige Kleinigkeit die sich nur für Android geändert hat, hat meiner App das Genick gebrochen. Nichts ging mehr &#8211; Nada, finito.</p>
<p>Aber um was genau geht es da? Nun ja, in meiner App wird ein selbst geschriebenes JSON/REST-Framework verwendet, dass mit einem Server-Framework interagiert. Als HTTP-Client wurde anfänglich auf den Apache Commons HttpClient gesetzt. Nachdem dieser unglaublich langsam ist im Vergleich zur UrlConnection &#8211; in meinen Tests um den Faktor 3,5 &#8211; wurde umgestellt.</p>
<p>So weit so gut, doch wo happert&#8217;s jetzt? Folgenden Code habe ich verwendet um die Verbindung aufzubauen, die Parameter an den Server zu schicken und dann den resultierenden InputStream zurück zu geben:</p>
<pre class="brush: java;">
				connection = (HttpURLConnection)myAppUrlObj.openConnection();
				connection.setDoOutput(true);
				connection.setDoInput(true);
				connection.setChunkedStreamingMode(0);
				OutputStream stream = connection.getOutputStream();

				authenticateIfPossible(request);

				writer = new OutputStreamWriter(new BufferedOutputStream(stream));
				appendTextParamsOnly(writer, request);
				writer.flush();
				writer.close();

				return connection.getInputStream();
</pre>
<p>Ich denke der Code ist so weit selbst erklärend. Dieser Code funktioniert auch wunderbar auf Android-Geräten die mit Android 2.2 oder älter betrieben werden. Aber wehe man verwendet ein neueres Model. Bumm: Der Server returniert seltsame Fehlermeldungen. In-Application-Fehlermeldungen, von wegen er kenne meinen Accesskey nicht. Was ist da los?</p>
<p>Nachdem alles mit dem JS-Tester abgeglichen ist, der fröhlich die Nachrichten an den Server schickt und gültige Resultate zurück gibt, ein JUnit-Test auf meiner Java SE VM ohne Probleme ebenfalls ein gültiges Resultat bekommt und dann auch noch die alte HttpClient-Implementierung auf Android 2.3 funktioniert ist es klar wer der Übeltäter ist.</p>
<p>Dann musst ich noch einen Tag warten, denn der Server-Mann sitzt in den Staaten, und dann wurde &#8211; bei ihm war es wohl 3 in der Früh &#8211; der Fehler gesucht. Schnell war klar, dem Server fehlt etwas. Wireshark meinte zwar, dass gültige Daten weg geschickt wurden, aber offensichtlich stimmte das Encoding nicht.</p>
<p>Schnell die Lösung dazu basteln:</p>
<pre class="brush: java;">
				connection = (HttpURLConnection)myAppUrlObj.openConnection();
				connection.setDoOutput(true);
				connection.setDoInput(true);
				connection.setRequestProperty(&quot;Content-type&quot;, &quot;application/json;charset=utf-8&quot;);
				connection.setChunkedStreamingMode(0);
				OutputStream stream = connection.getOutputStream();

				authenticateIfPossible(request);

				writer = new OutputStreamWriter(new BufferedOutputStream(stream), ENCODING);
				appendTextParamsOnly(writer, request);
				writer.flush();
				writer.close();

				return connection.getInputStream();
</pre>
<p>Oh Wunder, kaum macht man&#8217;s richtig funktioniert es auch &#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://schlingel.bplaced.net/?feed=rss2&amp;p=84</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Na no na ned &#8211; JQuery, Templates und CSS</title>
		<link>http://schlingel.bplaced.net/?p=81</link>
		<comments>http://schlingel.bplaced.net/?p=81#comments</comments>
		<pubDate>Tue, 21 Feb 2012 11:41:45 +0000</pubDate>
		<dc:creator>schlingel</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://schlingel.bplaced.net/?p=81</guid>
		<description><![CDATA[Hiermit möchte ich eine kleine Reihe starten die sich mit dummen Problemen beschäftigen die mir so im Alltag passieren bzw. die ich verursache und wie ich diese eigentlich offensichtlichen Fehler dann ausbügeln konnte. Im Folgenden geht es um HTML in &#8230;<p class="read-more"><a href="http://schlingel.bplaced.net/?p=81">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Hiermit möchte ich eine kleine Reihe starten die sich mit dummen Problemen beschäftigen die mir so im Alltag <em>passieren</em> bzw. die ich <strong>verursache</strong> und wie ich diese <em>eigentlich</em> offensichtlichen Fehler dann ausbügeln konnte.</p>
<p>Im Folgenden geht es um HTML in Verbindung mit JQuery und CSS. Wie es heutzutage üblich sind, baue ich gerade eine mehr oder weniger monströse App die massiv auf JS angewiesen ist. (Das ist allerdings auch keine Website sondern eine Spotify-App)</p>
<p>Mit JQuery gibt es mehrere Template-Frameworks. In meinem Fall sieht ein Template ca. so aus:</p>
<pre class="brush: xml;">
&lt;script id=&quot;myTmpl&quot; type=&quot;text/x-jquery-tmpl&quot;&gt;// &lt;![CDATA[
&lt;div class=&quot;wunderWuziMitFloatingLeft&quot;&gt;
    ${VAL1} ${VAL2}&lt;/div&gt;
// ]]&gt;&lt;/script&gt;
</pre>
<p>Ich hatte also ein komplexes Template das aus einem DIV bestand, welches in einer Liste floaten sollte. Was ich nicht bedacht hatte: Das verfluchte float zerschießt mir natürlich das restliche Layout das aus lauter absolut und relativ positionierten DIVs bestand.</p>
<p>Lösung? Die wunderWuzi-Klasse floatet jetzt nicht mehr sondern wird als <em>inline-box</em> angezeigt. Problem gelöst.</p>
]]></content:encoded>
			<wfw:commentRss>http://schlingel.bplaced.net/?feed=rss2&amp;p=81</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android &#8211; Wie wird das jetzt &#8220;smooth&#8221; und so</title>
		<link>http://schlingel.bplaced.net/?p=72</link>
		<comments>http://schlingel.bplaced.net/?p=72#comments</comments>
		<pubDate>Fri, 10 Feb 2012 19:36:48 +0000</pubDate>
		<dc:creator>schlingel</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://schlingel.bplaced.net/?p=72</guid>
		<description><![CDATA[Wenn man sich mit Android-UI Design beschäftigt, stößt man früher oder später auf Google IO Talks, die sich damit beschäftigen wie eine gute Android App aussehen und sich anfühlen soll. So wird in diesem Talk davon gesprochen, das eine gute App &#8230;<p class="read-more"><a href="http://schlingel.bplaced.net/?p=72">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Wenn man sich mit Android-UI Design beschäftigt, stößt man früher oder später auf <a href="http://www.youtube.com/results?search_query=google+io+android">Google IO Talks</a>, die sich damit beschäftigen wie eine gute Android App aussehen und sich anfühlen soll.</p>
<p>So wird in diesem <a href="http://www.youtube.com/watch?v=twmuBbC_oB8">Talk</a> davon gesprochen, das eine gute App folgende Eigenschaften haben sollte:</p>
<ul>
<li><strong>Fresh</strong> &#8211; Apps sollen sich immer auf aktuelle Daten beziehen, sie soll &#8220;immer Up to Date&#8221; sein.</li>
<li><strong>Psychic</strong> &#8211; Apps sollen die System-Ressourcen und das Android-Framework verwenden um Informationen über den Benutzer zu verwenden um dem Benutzer Arbeit zu ersparen. In solche Kategorien fallen z.B. Scrobbling und Vorschläge bei last.fm, automatisch in den Energiesparmodus nach 22 Uhr etc.</li>
<li><strong>Adaptiv</strong> &#8211; Die App existiert für den Benutzer nur als Kontext in dem er etwas erledigen möchte. Das bedeutet, dass die App niemals schlecht auffallen darf, z.B. wenn viel manuelle Texteingabe verlangt wird oder ähnlich &#8220;unmobile&#8221; Anforderungen in der UI gestellt werden. Die App soll wie die Unterhose sein: Hübsch wenn man sie sich bewusst anschaut aber im Alltag unsichtbar und bequem.</li>
<li><strong>Smooth</strong> &#8211; Die App soll schnell, flüssig und angenehm bzw. <em>responsive</em> reagieren.</li>
</ul>
<p>Mit dem letzten Punkt möchte ich mich in diesem kleinen Artikel beschäftigen. Doch zu aller erst die Fragen: Wie werden Anwendungen langsam, zäh und warum frieren sie ein?</p>
<p>Normalerweise werden im <em>onCreate </em>einer Activity-Klasse alle Objekte die während der Lebenszeit der Activity verwendet werden müssen initialisiert.</p>
<p>Das sind zum einen die relativ günstigen <em>findView-</em>Aufrufe und auf der anderen Seiten Objekte wie ListView-Adaptars, EventHandler, Code um auf Server zuzugreifen, Code um auf die SQLite-DB zuzugreifen, etc. Die Manigfaltigkeit der Performance-Fresser ist erschlagend groß.</p>
<p>Dazu kommen noch andere Todfeinde der Android-Smoothness:</p>
<ul>
<li>Der Garbace Collector, ein Erzschurke dessen Durchlauf mitunter 600ms Zeit kosten kann. Man spricht auch davon, dass er die Welt &#8220;anhält&#8221;.</li>
<li>Die versteckten Objektbrüter die den GC in Zugzwang bringen können. (Anonyme Klassen für Event-Handler, foreach-Schleifen die Iterator-Objekte anlegen, etc.)</li>
</ul>
<p>Doch auf diese Aspekte werde ich im folgenden nicht eingehen, sondern mich auf die onCreate-Problematik stürzen. Zu dem Thema GC und wie man ihn vermeidet sind vor allem Ressourcen zum Thema Spieleentwicklung sehr zu empfehlen. Siehe z.B. (<a href="http://www.amazon.de/Beginning-Android-Games-Richard-Taylor/dp/1430230428/">Beginning Android Game Development</a>, <a href="http://www.youtube.com/watch?v=_CruQY55HOk">Google IO Talks Memory Management</a>, <a href="http://www.youtube.com/watch?v=U4Bk5rmIpic">Android Real Time Game Development</a>)</p>
<p>Doch zurück zu <em>onCreate</em>, im folgenden möchte ich ein kleines Framework vorstellen, mit dem ich massive Verzögerungen durch ORMLite -und PageViewer- Instantiierungen schmerzlos gemacht habe.</p>
<p>Dem möchte ich allerdings eine Annahme vorausschicken, und zwar dass es dem Benutzer vollkommen egal ist ob eine Operation 200ms oder 2s dauert,  solange die App präsent ist und nicht einfach vor sich hinstockt bis endlich die Activity aufpoppt.</p>
<p>Unter dieser Prämisse sollte klar sein was im onCreate passieren darf:</p>
<ol>
<li>Die Content-View muss gesetzt werden.</li>
<li>Die View-Referenzen können gesetzt werden. Wie oben bereits geschrieben, sind die Aufrufe relativ günstig und verzögern den Aufbau der Activity auf meinem schwachbrüstigen Wildfire kaum. (<strong>Aufpassen</strong>: findView-Aufrufe dürfen <strong>nicht</strong> in andere Threads ausgelagert werden, weil nur der Thread auf die Referenz zugreifen darf, der sie auch hergestellt hat.)</li>
<li>Code anstarten, der die teuren Operationen in einem anderen Thread anstartet.</li>
</ol>
<p>Schauen wir uns doch einfach ein kleines Code-Beispiel an bei dem es sehr einfach ist die Schnecke zu finden:</p>
<pre class="brush: java;">
public class SlowAppTestActivity extends Activity {
    private ListView lvItems;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        lvItems = (ListView)findViewById(R.id.lvItems);
        ArrayAdapter&lt;String&gt; adapter = new ArrayAdapter&lt;String&gt;(this, R.layout.item, getItems());
        lvItems.setAdapter(adapter);
    }

    public List&lt;String&gt; getItems() {
    	final ArrayList&lt;String&gt; items = new ArrayList&lt;String&gt;();
    	for(int i = 0; i &lt; 35; i++) {
    		items.add(String.format(&quot;Number %d and very useful!&quot;, i));

    		// simple code to sleep ...
    		try {
    			Thread.sleep(200);
    		} catch(InterruptedException e) {e.printStackTrace();}
    	}

    	return items;
    }
}
</pre>
<p>Das zugehörige Layout sieht so aus:</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:layout_width=&quot;fill_parent&quot;
    android:layout_height=&quot;fill_parent&quot;
    android:orientation=&quot;vertical&quot; &gt;
    &lt;TextView
        android:layout_width=&quot;fill_parent&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:text=&quot;Ready!&quot; /&gt;
    &lt;ListView
        android:id=&quot;@+id/lvItems&quot;
        android:layout_width=&quot;fill_parent&quot;
        android:layout_height=&quot;fill_parent&quot; /&gt;
&lt;/LinearLayout&gt;
</pre>
<p>Also wenden wir jetzt mit dem <em>AsyncTask </em>aus dem Android-Framework die drei Punkte an. Zu erst setContentView und findView-Aufrufe erledigen. Im nächsten Schritt den Code für die asynchrone Ausführung anstarten und im letzten Schritt, wieder im UI-Thread, die UI updaten.</p>
<p>Mit diesen Anpassungen sieht das <em>onCreate</em> nun so aus:</p>
<pre class="brush: java;">
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        lvItems = (ListView)findViewById(R.id.lvItems);

        AsyncTask&lt;Void, Void, ArrayAdapter&lt;String&gt;&gt; task = new AsyncTask&lt;Void, Void, ArrayAdapter&lt;String&gt;&gt;() {

			@Override
			protected ArrayAdapter&lt;String&gt; doInBackground(Void... params) {
				ArrayAdapter&lt;String&gt; adapter = new ArrayAdapter&lt;String&gt;(SlowAppTestActivity.this, R.layout.item, getItems());
				return adapter;
			}

			@Override
			protected void onPostExecute(ArrayAdapter&lt;String&gt; adapter) {
				lvItems.setAdapter(adapter);
			}
		};

		task.execute();
    }
</pre>
<p>Es steht jedem frei beide Varianten auszuprobieren. Der Unterschied ist enorm. Doch wie kann man diesen Teil sinnvoll abstrahieren um es an mehreren Stellen zu verwenden?</p>
<p>Schauen wir uns, unsere drei Schritte noch einmal an. Der erste Schritt kann genau wie er ist im onCreate bleiben. Hier macht es also keinen Sinn herumzudoktern, dito für den zweiten Schritt. Der dritte Schritt wird schon interessanter, denn es soll etwas asynchron ausgeführt werden.</p>
<p>Im letzten Teil soll wieder etwas synchron im UI-Thread ausgeführt werden. Daraus lassen sich nun zwei Methoden ableiten die wir gleich in ein Interface gießen:</p>
<pre class="brush: java;">
public interface IAsyncWorker {
	public void processAsync();

	public void onAsyncFinish();
}
</pre>
<p>Jetzt ist klar <strong>was</strong> passieren soll, aber <strong>wer</strong> erledigt es? Eine einfache Klasse namens AsyncWorkerLauncher bietet sich dafür an.</p>
<pre class="brush: java;">
public class AsyncWorkerLauncher extends AsyncTask&lt;Void, Void, Void&gt; {
	private final IAsyncWorker worker;

	public static AsyncWorkerLauncher from(IAsyncWorker worker) {
		return new AsyncWorkerLauncher(worker);
	}

	public AsyncWorkerLauncher(IAsyncWorker worker) {
		this.worker = worker;
	}

	@Override
	protected Void doInBackground(Void... params) {
		worker.processAsync();
		return null;
	}

	@Override
	protected void onPostExecute(Void result) {
		worker.onAsyncFinish();
	}
}
</pre>
<p>Mit diesen paar Zeilen Code kann jetzt unsere Activity umgebaut werden:</p>
<pre class="brush: java;">
public class SlowAppTestActivity extends Activity implements IAsyncWorker{
    private ListView lvItems;

    ArrayAdapter&lt;String&gt; adapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        lvItems = (ListView)findViewById(R.id.lvItems);
        AsyncWorkerLauncher.from(this).execute();
    }

    public List&lt;String&gt; getItems() {
    	final ArrayList&lt;String&gt; items = new ArrayList&lt;String&gt;();
    	for(int i = 0; i &lt; 35; i++) {
    		items.add(String.format(&quot;Number %d and very useful!&quot;, i));

    		// simple code to sleep ...
    		try {
    			Thread.sleep(200);
    		} catch(InterruptedException e) {e.printStackTrace();}
    	}

    	return items;
    }

	@Override
	public void processAsync() {
		adapter = new ArrayAdapter&lt;String&gt;(SlowAppTestActivity.this, R.layout.item, getItems());
	}

	@Override
	public void onAsyncFinish() {
		lvItems.setAdapter(adapter);
	}
}
</pre>
<p>Und Bumm: Plötzlich haben wir eine Activity die sich tatsächlich <em>smooth</em> anfühlt und deren Code nicht umständlicher zu lesen ist.</p>
<p>Das Projekt findent man übrigens hier: <a href='http://schlingel.bplaced.net/wp-content/uploads/2012/02/SlowAppTest1.zip'>SlowAppTest</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://schlingel.bplaced.net/?feed=rss2&amp;p=72</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Werkstatts-Update</title>
		<link>http://schlingel.bplaced.net/?p=65</link>
		<comments>http://schlingel.bplaced.net/?p=65#comments</comments>
		<pubDate>Wed, 08 Feb 2012 18:22:00 +0000</pubDate>
		<dc:creator>schlingel</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://schlingel.bplaced.net/?p=65</guid>
		<description><![CDATA[Die letzten Monate hatte ich kaum Zeit mich eigenen Projekten zu widmen. Sei es die Universität, der Job oder ganz einfach Sport &#8211; welchen ich bitter notwendig habe &#8211; der mich vom Codieren und Experimentieren abgehalten haben. Doch so untriebig &#8230;<p class="read-more"><a href="http://schlingel.bplaced.net/?p=65">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Die letzten Monate hatte ich kaum Zeit mich eigenen Projekten zu widmen. Sei es die Universität, der Job oder ganz einfach Sport &#8211; welchen ich bitter notwendig habe &#8211; der mich vom Codieren und Experimentieren abgehalten haben.</p>
<p>Doch so untriebig war ich dann auch wieder nicht. Seit Oktober 2011 bin ich Programmierer in einem Startup und habe damit die Gefilde der Enterprise-Softwareschmieden verlassen um in die vermeintlich &#8220;niederen&#8221; Gefilde der Jungunternehmen abzusteigen.</p>
<p>Das tolle daran ist, dass ich jetzt nicht mehr auf JEE oder .Net Enterprise Entwicklung gebunden bin und dementsprechend mit Frameworks arbeiten darf, die auch Spaß machen.</p>
<p>Zu aller erst wäre da Android. Jede Woche arbeite ich mich weiter in dieses Framework hinein, fluche und zürne über Design-Entscheidungen, staune über die Google IO-Präsentationen und hacke Java so viel wie noch nie.</p>
<p>Eines darf ich verraten: Es ist eine Neuentwicklung und ich baue mein Haus auf einer grünen Wiese!</p>
<p>Dazu kommen Javascript bzw. JQuery und HTML5. Up to date, nicht nur in der Freizeit sondern endlich auch beruflich.</p>
<p>Doch um es knackig zusammen zu fassen mit welchen Frameworks ich mich zur Zeit beruflich oder privat beschäftige:</p>
<ul>
<li>Play Framework (Java Web-Entwicklung, die Spaß macht!</li>
<li>Android Framework</li>
<li>HTML5/Javascript</li>
</ul>
<p>Doch welche Ideen trage ich mit mir herum die es wert sind umgesetzt zu werden?</p>
<ul>
<li>Haushaltsbuch-App: Die Idee ist schnell erklärt, denn dabei handelt es sich um ein Haushaltsbuch das immer dabei ist. Der Grundgedanke ist alle Ausgaben aufzuzeichnen und zwar dann wenn sie passieren. Bonus: Server-Anwendung mit Play-Framework.</li>
<li>Ernährungs- und Trainingstagebuch-App: Wieder eine simple Anwendungen deren Zweck aus meiner eigenen Faulheit kommt. Ich schaffe es einfach nicht mich aufzuraffen und diese Daten am PC einzutragen oder auch nur in ein Büchlein einzutragen. Denn diese Büchlein neigen dazu nie dort zu sein wo ich sie gerade haben möchte.</li>
<li>Musikkenner-App: Was soll das sein? Manchmal sitze ich da und browse durch meine MP3-Files und bin absolut unzufrieden. Ich ordne den einzelnen CDs Jahre zu und fühle mich wie jemand, der dumpf in der Vergangenheit wühlt, wenn ich dann doch Musik starte. Also muss neues her! Die Idee: Eine Anwendung schreiben die, die lokale Musikdatenbank scrobbled und dann Vorschläge anhand des vorgefundenen Musikgeschmacks machen. Als nötige Wissensdatenbank könnten dabei Echonest, Yahoo Music oder Musicbrainz herhalten.</li>
<li>Ein paar Android-Spiele.</li>
</ul>
<p>Neben diesen Ideen beschäftige ich mich auch damit, auf java-forum.org hilfreich zur Stelle zu sein um durch auftretende Fragen etwas zu lernen. Stackoverflow gehört hier natürlich auch genannt.</p>
]]></content:encoded>
			<wfw:commentRss>http://schlingel.bplaced.net/?feed=rss2&amp;p=65</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ghostscript and ps2pdf &#8211; A little odyssey</title>
		<link>http://schlingel.bplaced.net/?p=54</link>
		<comments>http://schlingel.bplaced.net/?p=54#comments</comments>
		<pubDate>Thu, 21 Jul 2011 10:10:09 +0000</pubDate>
		<dc:creator>schlingel</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://schlingel.bplaced.net/?p=54</guid>
		<description><![CDATA[Recently I had to update some 3rd-party software in our server environment. We&#8217;re using Ghostscript as weapon of choice for converting PS-files in PDF-files. As you may know there is a special BAT-file for this purpose in the lib directory &#8230;<p class="read-more"><a href="http://schlingel.bplaced.net/?p=54">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Recently I had to update some 3rd-party software in our server environment. We&#8217;re using Ghostscript as weapon of choice for converting PS-files in PDF-files.</p>
<p>As you may know there is a special BAT-file for this purpose in the lib directory of the Ghostscript directory.</p>
<p>If you use the <em>ps2pdf.bat</em> or in a *nix-enviornment the ps2pdf-file there you have to specifiy at least the source- and the destination-file for the command. The command itself writes the parameters in a  temp-file in the temp-directory because the authors are frightened to overrun the command buffer in the shell.</p>
<p>This little detail makes it essential for you to correctly set the <em>TEMP</em> and the <em>TMP</em> environment variable. Because if you don&#8217;t, you do not know for sure where the variable is pointing to.</p>
<p>In my case I had to figure out why the command did work as a charme when I ran it in a shell but failed when it ran itside a self written Job-Framework.</p>
<p>The log displayed following error message:</p>
<pre class="brush: plain;">Ghostscript 8.60: **** Could not open temporary file ''</pre>
<p>and<span style="font-family: Consolas, Monaco, 'Courier New', Courier, monospace; line-height: 18px; white-space: pre;">
<pre class="brush: plain;">**** Unable to open the initial device, quitting.</pre>
<p></span></p>
<p>But why did this happen? I don&#8217;t know exactly but I think it has to do with the difference between a regular user and a very restricted service-user.<br />
I&#8217;m writing this in English because I couldn&#8217;t find a good explanation for the problem with ghostscript 8.60. If you search just for &#8216;Ghostscript **** Could not open temporary file &#8221;&#8217; you&#8217;ll get really fast good explanations but sometimes I&#8217;m just a blockhead. I hope this short blog article helps somebody.</p>
<p>But after getting the old version running I had to update to version 9.02. Because I use the 64 bit version. I first tried 9.01 but the gswin64c.exe and the gswin64.exe just stopped working with an unexpected error so I switched to the newest version.</p>
<p>But – and that&#8217;s a really annoying point – the people from Ghostscript didn&#8217;t update the BAT-files. So the environment variables which get set in the gssetgs.bat point to non existing gswin32-exes.</p>
<p>To get this running just change the lines:</p>
<pre class="brush: plain;">
if %GS%/==/ set GS=gswin32
if %GSC%/==/ set GSC=gswin32c
</pre>
<pre class="brush: plain;">
if %GS%/==/ set GS=gswin64
if %GSC%/==/ set GSC=gswin64c
</pre>
<p>And don&#8217;t forget to add the needed directories to the path variable when you try to run ps2pdf. In the new version you not only have to add the Ghostscript directories</p>
<pre class="brush: plain;">
 %ProgramFiles%\gs\gs9.02\lib
 %ProgramFiles%\gs\gs9.02\bin
</pre>
<p>You also have to add a directory with a strfind.exe init. In a 64-bit environment that&#8217;s:</p>
<pre class="brush: plain;">%windir%\SysWOW64</pre>
<p>So to get the new ps2pdf.bat running you have to change the gssetgs.bat file to the following:</p>
<pre class="brush: plain;">
@echo off
@rem $Id: gssetgs.bat 6300 2005-12-28 19:56:24Z giles $

rem Set default values for GS (gs with graphics window) and GSC
rem (console mode gs) if the user hasn't set them.

if %GS%/==/ set GS=gswin64
if %GSC%/==/ set GSC=gswin64c

set path=%ProgramFiles%\gs\gs9.02\lib;%ProgramFiles%\gs\gs9.02\bin;%windir%\SysWOW64
set TMP=%YOUR_TEMP%
set TEMP=%TMP%
</pre>
]]></content:encoded>
			<wfw:commentRss>http://schlingel.bplaced.net/?feed=rss2&amp;p=54</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rudimentary Stack Environment &#8211; Forth ähnliche Skriptsprache</title>
		<link>http://schlingel.bplaced.net/?p=32</link>
		<comments>http://schlingel.bplaced.net/?p=32#comments</comments>
		<pubDate>Sun, 19 Dec 2010 12:52:29 +0000</pubDate>
		<dc:creator>schlingel</dc:creator>
				<category><![CDATA[Forth]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[RSE]]></category>

		<guid isPermaLink="false">http://schlingel.bplaced.net/?p=32</guid>
		<description><![CDATA[Die Idee Die letzten Wochen und Monate waren beinahe vollkommen von meinem Studium und meiner neuen Arbeit ausgefüllt. Doch da ich noch immer viele Wege habe, bin ich auf den Fahrten etwas zum Lesen gekommen. Da ich gerade eine Lehrveranstaltung &#8230;<p class="read-more"><a href="http://schlingel.bplaced.net/?p=32">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<h2>Die Idee</h2>
<p>Die letzten Wochen und Monate waren beinahe vollkommen von meinem Studium und meiner neuen Arbeit ausgefüllt. Doch da ich noch immer viele Wege habe, bin ich auf den Fahrten etwas zum Lesen gekommen. Da ich gerade eine Lehrveranstaltung mit dem Thema Stackbasierte Sprachen besuche, habe ich mir auch gleich die PDF-Version von <a href="http://thinking-forth.sourceforge.net/">Thinking Forth</a> gekrallt. Dank meines neuen EBook-Readers, lese ich es jetzt sogar.</p>
<p>Dabei kam mir ein altes .Net-Projekt wieder in Sinn: RSE NonForth, eine Skriptsprache deren Prinzip nahtlos an das von Forth anschließt:</p>
<ul>
<li>Kommandos bzw. <em>Words</em> exekutieren Code.</li>
<li>Der Interpreter ist <em>dumm</em> und bietet außer der Infrastruktur eines Stacks, Dictionaries &#8211; quasi Namespaces &#8211; und einer Handvoll Primitives zum Nachladen anderer Bibliotheken überhaupt keine Funktionalität.</li>
</ul>
<p>Dadurch war es sehr leicht möglich &#8211; auch ohne akademische Erfahrung &#8211; einen funktionierenden Interpreter zu schreiben. Da ich mich bei meiner neuen Stelle für eine Java-Firma entschieden habe &#8211; mir persönlich ist .Net nach wie vor sympathischer aber das Unternehmen war wiederum sympathischer als die .Net-Firmen &#8211; werde ich das ganze Ding wohl neu in Java schreiben und schon in der ersten Version die Möglichkeit von Chainlets inkludieren.</p>
<h2>Chainlets &#8211; WTF?</h2>
<p>Die Grundidee von Chainlets fußt auf der Vorstellung von untereinander verknüpfbaren Widgets. Also: Warum kann ich z.B. nicht mein Widget dass mir die Übersicht aller Kalendareinträge präsentiert nicht beibringen, dass es den Termin einem beliebigen anderen Widget per Doppelclick übermittelt?</p>
<p>Ganz einfach darum nicht, da es den Widget-Plattformen die ich kenne, wie z.B. die von Windows oder die Vorschläge von W3C, keine Infrastruktur für solche Aufgaben zur Verfügung stellen. Ich habe dann lang herum überlegt wie diese Schnittstelle zu <strong>beliebigen </strong>anderen Widgets funktionieren könnte und bin zu dem Schluss gekommen, dass dies am einfachsten in einer Stackgetriebenen Umgebung möglich wäre.</p>
<p>So werden die einzelnen Widgets vollkommen von einander entkoppelt und sie können zusammen arbeiten wie es der Programmierer vorsieht. Er muss die einzelnen Widgets nur untereinander <strong>verketten</strong>.</p>
<p>Damit war auch gleich die Begrifflichkeit gefunden: Chainlets.</p>
<h2>Aber Forth &#8230;</h2>
<p>Forth hat jetzt natürlich einen Nachteil &#8211; jedenfalls für so eine Scripting Engine &#8211; ich müsste einiges herumdoktoren damit ich beliebige Objekte auf den Stack legen kann. Natürlich könnte das mit Adressen funktionieren zu denen im Bedarfsfall gesprungen aber im Endeffekt entwickelt sich die Vorstellung zu einer gar grausigen Angelegenheit.</p>
<p>Darum schreibe ich einen Interpreter dessen Syntax der von Forth ähnlich ist und deren Philosophie sowie Handling einiges an Ähnlichkeiten aufweist aber dennoch etwas ganz anderes ist.</p>
<p>Jedem der an dieser Stelle keine Ahnung hat wovon ich hier schreibe lege ich folgende zwei Lektüren ans Herz:</p>
<ul>
<li><a href="http://home.iae.nl/users/mhx/sf.html">Starting Forth</a> &#8211; Eine Einführung die dem interessierten Programmierer eine neue Art des Denkens mithilfe von Forth zeigt.</li>
<li><a href="http://thinking-forth.sourceforge.net/">Thinking Forth</a> &#8211; Ein Buch über das (Kunst-)Handwerk Software Entwicklung mit Forth. (Sehr interessant da hier sehr schön gezeigt wird, dass iterative Modelle wie Scrum schon in den 80ern existierten und von Forth-Codern angewandt wurden.)</li>
</ul>
<h2>Der Aufbau</h2>
<p>Ganz grob u. simpel aufgezeichnet wird das System so aussehen:</p>
<p><a href="http://schlingel.bplaced.net/wp-content/uploads/2010/12/RSE-Simple-System-Architecture.png"><img class="aligncenter size-full wp-image-43" title="RSE Simple System Architecture" src="http://schlingel.bplaced.net/wp-content/uploads/2010/12/RSE-Simple-System-Architecture.png" alt="" width="690" height="510" /></a></p>
<p>Dabei sticht ins Auge, dass eine Unterscheidung zwischen <em>Word </em>u. einem so genannten <em>System Word</em> existiert. Der Unterschied ist schnell erklärt: Da in diesem System alle Words <em>immediate</em> sind, wird das Word sobald es in der Queue selektiert wird ausgeführt.</p>
<p>Von dort aus kann es dann aber noch weiter Einfluss auf den Programmfluss nehmen. Ein gutes Beispiel dafür ist z.B. ein IF oder eine Schleife wie +LOOP. Ein IF muss z.B. wissen welche nachfolgenden Words in den eigenen Bereich fallen. Dazu benötigt es mehr Zugriff auf das System also nur den Daten-Stack.</p>
<p>Da aber nicht alle Word so einen Zugriff auf das System benötigen, wie z.B. DUP oder DROP, existieren auch explizit Words die nur Zugriff auf den Stack haben.</p>
<p>Das Diagramm ist schön u. gut aber wie sieht der Ablauf aus?</p>
<p><a href="http://schlingel.bplaced.net/wp-content/uploads/2010/12/RSE-VM-Activity1.png"><img class="aligncenter size-full wp-image-41" title="RSE VM Activity" src="http://schlingel.bplaced.net/wp-content/uploads/2010/12/RSE-VM-Activity1.png" alt="" width="810" height="720" /></a></p>
<p>Soweit so gut. Nun ist es wohl an der Zeit mit dem Schwafeln aufzuhören und mit dem Coden anzufangen.</p>
]]></content:encoded>
			<wfw:commentRss>http://schlingel.bplaced.net/?feed=rss2&amp;p=32</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Picknick &#8211; Seltsamer explode-Bug</title>
		<link>http://schlingel.bplaced.net/?p=28</link>
		<comments>http://schlingel.bplaced.net/?p=28#comments</comments>
		<pubDate>Mon, 20 Sep 2010 09:43:49 +0000</pubDate>
		<dc:creator>schlingel</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[picknick]]></category>
		<category><![CDATA[webdeveloping]]></category>

		<guid isPermaLink="false">http://schlingel.bplaced.net/?p=28</guid>
		<description><![CDATA[Die letzten Tage versuche ich Picknick tatsächlich produktiv für ein kleines privates Projekt einzusetzen. Was mir sauer aufstößt sind plötzlich Bugs die ich auf meinem Windows-Entwicklungssystem nicht hatte. Dabei geht es zum einen um die übliche Problematik die nicht bedacht &#8230;<p class="read-more"><a href="http://schlingel.bplaced.net/?p=28">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Die letzten Tage versuche ich Picknick tatsächlich produktiv für ein kleines privates Projekt einzusetzen. Was mir sauer aufstößt sind plötzlich Bugs die ich auf meinem Windows-Entwicklungssystem nicht hatte.</p>
<p>Dabei geht es zum einen um die übliche Problematik die nicht bedacht wurde und ganz sauber auf die OS-API zurückzuführen sind. Also z.B. bei Dateinamenvergleiche prüft Windows &#8211; jedenfalls nicht Windows 7 &#8211; nicht auf gleiche Großkleinschreibung, Linux schon. Natürlich vollkommen dämlich und meine Schuld.</p>
<p>Doch dann ein Bug in PHP selbst der wieder nur in Linux auftritt. Die Funktion <a href="http://php.net/manual/de/function.explode.php">explode</a> lieferte &#8211; ohne ersichtlichen Grund &#8211; Nullwerte im resultierenden Array. Was zum Teufel?  Zu aller erst dachte ich, ich wäre der einzige der diesen Fehler &#8220;gefunden&#8221; hat und darunter leidet doch dann fand ich diesen <a title="Link to explode question" href="http://bytes.com/topic/php/answers/583179-delete-null-elements-array">Eintrag</a>.</p>
<p>Dort wurde das ganze auf doppelte Leerzeichen zurückgeführt die bei mir nicht auftraten da ich anhand eines &#8220;/&#8221; trenne. Was also tun? Zum einen hätte ich mit Regex drüberfahren können, doch die Implementation von Regex gefällt mir in PHP nicht weswegen ich zu einer simplen For-Schleife mit einer darin enthaltenen If-Abfrage gegriffen habe.</p>
<pre class="brush: php;">
    /**
     * Calls explode with '/' as delimiter on $url and removes every empty
     * string in the resulting array and returns this array.
     * @param string $url
     * @return array(string)
     */
    private function GetUrlParts($url) {
        // I had to use this because on a free linux webserver explode didn't
        // work properly and returned empty fields in the array which lead to
        // errors
        $nonFilteredParts = explode('/', $url);
        $filteredParts = array();
        $filteredIndex = 0;

        for($i = 0; $i &lt; count($nonFilteredParts); $i++) {
            $element = $nonFilteredParts[$i];

            if(strlen($element) &gt; 0) {
                $filteredParts[$filteredIndex] = $element;
                $filteredIndex++;
            }
        }

        return $filteredParts;
    }
</pre>
<p>Anstatt explode(&#8216;/&#8217;, $var) wird nun oben genannte Methode aufgerufen. Funktioniert nun, ist auch schon im Git-Repo eingechecked.</p>
]]></content:encoded>
			<wfw:commentRss>http://schlingel.bplaced.net/?feed=rss2&amp;p=28</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

