<?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>SyndicateX.com</title>
	<atom:link href="http://syndicatex.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://syndicatex.com</link>
	<description>Justin Johnson: CodeMonkey</description>
	<lastBuildDate>Fri, 10 Feb 2012 21:07:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Kicked out by Kickstarter</title>
		<link>http://syndicatex.com/projects/kicked-out-by-kickstarter/</link>
		<comments>http://syndicatex.com/projects/kicked-out-by-kickstarter/#comments</comments>
		<pubDate>Fri, 10 Feb 2012 21:07:49 +0000</pubDate>
		<dc:creator>jjohnson</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[grimwar]]></category>
		<category><![CDATA[kickstarter]]></category>
		<category><![CDATA[MVC3]]></category>

		<guid isPermaLink="false">http://syndicatex.com/?p=435</guid>
		<description><![CDATA[I&#8217;ve written about Grimwar several times on here. I keep trying to rebuild it and make it better but it&#8217;s a very big site with a lot of users and there is a lot of work involved with rebuilding. That being said, I AM rebuilding it. Even though it makes no money, even though I don&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve written about Grimwar several times on here. I keep trying to rebuild it and make it better but it&#8217;s a very big site with a lot of users and there is a lot of work involved with rebuilding. That being said, I AM rebuilding it. Even though it makes no money, even though I don&#8217;t even <em>play </em>Magic the Gathering, I think it <em>could </em>be profitable and I want to build it for the community, if nothing else.</p>
<p>I am rebuilding Grimwar in .NET MVC3 and it&#8217;s going really well. Unfortunately, Windows servers are more expensive than the LAMP servers I&#8217;m used to rolling on. I created and submitted a Kickstarter proposal to help raise money for some marketing expenses, printing expenses and server costs. Unfortunately my request was denied. Here&#8217;s what they had to say:</p>
<blockquote><p>Hi Justin,</p>
<p>Thank you for taking the time to share your idea. Unfortunately, this isn&#8217;t the right fit for Kickstarter. We receive many project proposals daily and review them all with great care and appreciation. We see a wide variety of inspiring ideas, and while we value each one&#8217;s uniqueness and creativity, Kickstarter is not the right platform for all of them. We wish you the best of luck as you continue to pursue your endeavor.</p>
<p>Best,<br />
Kickstarter</p></blockquote>
<p>So&#8230;denied! I think Kickstarter is more interested in projects that further the arts, or technology. Grimwar is unique in that no other site serves the same function. However, it&#8217;s not particularly ground-breaking. So, I&#8217;m disappointed that I don&#8217;t even get the <em>chance </em>to try to get funding but I like that Kickstarter has a good gatekeeping system.</p>
<p>Anyway, I thought the processes of submitting a proposal, getting reviewed by real people and the gatekeeping thing was interesting. I still love you Kickstarter, maybe we can work together another time.</p>
<p>&nbsp;</p>
<p><em>Note: I can make Grimwar work regardless of securing funding. I&#8217;ll dump an existing server and pick up some shared Windows hosting. So, if you&#8217;re reading this and concerned about the future of Grimwar&#8230;the show will go on!</em></p>
]]></content:encoded>
			<wfw:commentRss>http://syndicatex.com/projects/kicked-out-by-kickstarter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Binary Serialization in C#</title>
		<link>http://syndicatex.com/programming/binary-serialization-in-c/</link>
		<comments>http://syndicatex.com/programming/binary-serialization-in-c/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 23:09:28 +0000</pubDate>
		<dc:creator>jjohnson</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[auto-properties]]></category>
		<category><![CDATA[binary]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[deserialization]]></category>
		<category><![CDATA[persistent storage]]></category>
		<category><![CDATA[serialization]]></category>

		<guid isPermaLink="false">http://syndicatex.com/?p=433</guid>
		<description><![CDATA[Let me preface this by saying I&#8217;m not sure the information here is correct. Prior to this, I have not worked with binary serialization. I serialized to XML or JSON because it was easy to transfer and was human readable. But binary really makes sense for what I&#8217;m doing now. I deserialize JSON into objects [...]]]></description>
			<content:encoded><![CDATA[<p>Let me preface this by saying I&#8217;m <strong>not sure the information here is correct</strong>. Prior to this, I have not worked with binary serialization. I serialized to XML or JSON because it was easy to transfer and was human readable. But binary really makes sense for what I&#8217;m doing now. I deserialize JSON into objects from a Web API. To make the app run faster, I cache the deserialized objects. Many of them could be cached for quite awhile because they rarely change. So, persistent cache storage is good but I need to keep the cache footprint small on disk and keep serialization speedy. Binary is faster and smaller than any other type (afaik). It also supposedly preserves links and hierarchies more reliably.</p>
<p>Here&#8217;s a shortened example of a type of object I get from JSON and want to save persistently:</p>
<pre class="brush:csharp">[Serializeable()]
public class Department {
   public int Id {get; set;}
   public string Name {get; set;}
   public Drawable Thumbnail {get; set;} // Drawable is an android type that holds image data
}</pre>
<p>&nbsp;</p>
<p>The above example will not serialize because the Android Drawable class is not serializable. We probably don&#8217;t want to be serializing image data into our cache anyway so&#8230;let&#8217;s mark that as [NonSerialized]. Now we get a new exception because you can&#8217;t mark a property as non-serialized&#8230;because Properties aren&#8217;t serialized! Yet, if you comment out the Thumbnail property the rest of the class can be serialized and deserialized with no problems. Why?</p>
<p>Traditionally, auto-properties didn&#8217;t exist. You had to have an explicit class member defined and manually create the accessors. When we create an auto-property (which are awesome, IMHO) the compiler creates a class member behind the scenes that the auto-property references. But this is given an arbitrary name and is not accessible. So, when you serialize a property, the property is not being serialized, the hidden member behind it is being serialized. This has some very important consequences.</p>
<p>Let&#8217;s say you create the class above and the data is serialized and stored on disk. As time moves on you have some updates to make that require name to perform some logic. Perhaps it simply needs to upper case the name before returning it. So, you create an explicit member variable and your code looks like this:</p>
<pre class="brush:csharp">[Serializeable()]
public class Department {
   public int Id {get; set;}
   public Drawable Thumbnail {get; set;} // Drawable is an android type that holds image data
   public string Name {
      get {
         return mName.ToUpper();
      }
      private set {
         mName = value;
      }
   }
   private string mName;
}</pre>
<p>Unfortunately for you, when your program deserializes the data from the old version, Name and mName are going to be <em>null</em>. This is because the actual serialized member behind Name was called something else and that&#8217;s what was serialized. If you serialize again and save before you realize this, your binary data will now have a bunch of empty names. The worst part is: it won&#8217;t even warn you! It simply doesn&#8217;t inflate the old member because it no longer exists as part of the class and the new member is left as its default (null for strings).</p>
<p>The above would still fail because it doesn&#8217;t solve the problem of Drawables being unserializeable (is that even a word?). To fix this, you have to give Thumbnail an explicit class member and mark the member as [NonSerialized]. Remember, if you mark a class as [Serializeable()] it will try to serialize the whole thing, even private members.</p>
<p>So, the ultimate thing to be aware of is: be really careful using auto-properties with binary serialization. If you have auto-properties that have ANY CHANCE of changing and data integrity is important&#8230;explicitly define the backing members.</p>
]]></content:encoded>
			<wfw:commentRss>http://syndicatex.com/programming/binary-serialization-in-c/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Mono for Android List Optimization</title>
		<link>http://syndicatex.com/programming/monodroid-list-optimization/</link>
		<comments>http://syndicatex.com/programming/monodroid-list-optimization/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 17:21:56 +0000</pubDate>
		<dc:creator>jjohnson</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[mono]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[ViewHolder]]></category>

		<guid isPermaLink="false">http://syndicatex.com/?p=426</guid>
		<description><![CDATA[One of the big things I&#8217;ve worked on lately is optimization of the Android app I&#8217;m working on for my employer. I want the app to run at its absolute full potential using every realistic optimization I can. One of the most-frequently-used components in Android applications are ListViews. Android ListViews are good and bad. They [...]]]></description>
			<content:encoded><![CDATA[<p>One of the big things I&#8217;ve worked on lately is optimization of the Android app I&#8217;m working on for <a title="Sierra Trading Post" href="http://www.sierratradingpost.com/" target="_blank">my employer</a>. I want the app to run at its absolute full potential using every realistic optimization I can.</p>
<p>One of the most-frequently-used components in Android applications are ListViews. Android ListViews are good and bad. They are good in that, if you do it properly, they handle view recycling and can be pretty efficient. They are bad in that the abstraction is so leaky that 90% of the so-called tutorials and examples I&#8217;ve seen do it poorly. Many of the tutorials don&#8217;t even take advantage of the view recycling and the ones that do still miss out on some important optimizations.</p>
<p>This is a quick example of how to optimize a list view, starting with bad implementation and moving to better implementation. Note that I&#8217;m mocking up this code so please point out any mistypes in the comments.</p>
<p>&nbsp;</p>
<p>Here&#8217;s an example of the most basic implementation of a ListAdapter&#8217;s GetView method. Please <strong>do not</strong> create your list like this. This would be fine for viewing just a few items but it doesn&#8217;t take advantage of any recycling. This is inflating a new view every, single time &#8211; which is extremely wasteful and will definitely slow your lists down. Notice that we&#8217;re not using the &#8220;convertView&#8221; parameter at all! We will implement that in the next example.</p>
<pre class="brush:csharp">public override View GetView(int position, View convertView, ViewGroup parent)
{
   // get our data object from the list
   MyObject dataObject = mObjectList[position];

   // inflate our custom line item
   LinearLayout view = mContext.LayoutInflater.Inflate(Resource.Layout.my_line_item, parent, false) as LinearLayout;

   // get references to our views
   TextView title = view.FindViewById(Resource.Id.myLineItemTitle) as TextView;
   TextView subText = view.FindViewById(Resource.Id.myLineItemSubtext) as TextView;
   ImageView thumbnail = view.FindViewById(Resource.Id.myLineItemThumb) as ImageView;

   // bind data to our line item
   title.Text = dataObject.Title;
   subText.Text = dataObject.Description;
   thumbnail.SetImageDrawable(dataObject.Thumb);

   return view;
}</pre>
<p>&nbsp;</p>
<p>This version improves slightly. Here we are using the recycled convertView, if it exists, instead of inflating a new view. This will help a lot but we still have to instantiate references to our sub views before we can bind data. FindViewById is expensive enough that this still adds overhead. If your line item is simple enough that it doesn&#8217;t have subviews or only has a single subview this method might be okay but use it with caution.</p>
<pre class="brush:csharp">public override View GetView(int position, View convertView, ViewGroup parent)
{
   // get our data object from the list
   MyObject dataObject = mObjectList[position];

   // check if we have a recycled view, if not then inflate
   var view = convertView;
   if(convertView == null)
   {
      view = mContext.LayoutInflater.Inflate(Resource.Layout.my_line_item, parent, false) as LinearLayout;
   }

   // get references to our views
   TextView title = view.FindViewById(Resource.Id.myLineItemTitle) as TextView;
   TextView subText = view.FindViewById(Resource.Id.myLineItemSubtext) as TextView;
   ImageView thumbnail = view.FindViewById(Resource.Id.myLineItemThumb) as ImageView;

   // bind data to our line item
   title.Text = dataObject.Title;
   subText.Text = dataObject.Description;
   thumbnail.SetImageDrawable(dataObject.Thumb);

   return view;
}</pre>
<p>&nbsp;</p>
<p>So, that was an easy way to make sure we&#8217;re using our recycled views. But we still are finding sub views every time. To fix this we implement something called the ViewHolder Pattern. Views in Android have something called a Tag. A Tag can be any type of Java.Lang.Object that is stored in the View.Tag for future use. The idea here is to create a ViewHolder class that will store references to our subviews so that we only have to find them once. Then we store that reference in the View.Tag and retrieve it when we need it. I take this even further and create a &#8220;Bind&#8221; method so that my GetView method is really clean!</p>
<pre class="brush:csharp">// our GetView method is now very clean!
public override View GetView(int position, View convertView, ViewGroup parent)
{
   ViewHolder vh;

   // attempt to recycle existing view
   var view = convertView;
   if(view == null)
   {
      view = mContext.LayoutInflater.Inflate(Resource.Layout.my_line_item, parent, false) as LinearLayout;
      vh = new ViewHolder();

      // here's where we get our subview references
      vh.Initialize(view);

      // push the viewholder reference into the view tag
      view.Tag = vh;
   }

   // get our data object
   MyObject dataObject = mObjectList[position];

   // get our viewholder from the tag
   vh = (ViewHolder)view.Tag;

   // bind our data!
   vh.Bind(dataObject);
   return view;
}

// extend Java.Lang.Object or you will run into all kinds of type/cast issues when trying to push/pull on the View.Tag
private class ViewHolder : Java.Lang.Object
{
   TextView mTitle;
   TextView mSubText;
   ImageView mThumb;

   // this method now handles getting references to our subviews
   public void Initialize(View view)
   {
      mTitle = view.FindViewById(Resource.Id.myLineItemTitle) as TextView;
      mSubText = view.FindViewById(Resource.Id.myLineItemSubtext) as TextView;
      mThumb = view.FindViewById(Resource.Id.myLineItemThumb) as ImageView;
   }

   // this method now handles binding data
   public void Bind(MyObject data)
   {
      mTitle.Text = data.Title;
      mSubText.Text = data.Description;

      // we've also improved the thumbnail to use a default image if missing
      if(data.Thumb == null)
      {
         mThumb.SetImageResource(Resource.Drawable.missing_thumb);
      }
      else
      {
         mThumb.SetImageDrawable(data.Thumb);
      }
   }
}</pre>
<p>Now we only instantiate a view if we don&#8217;t already have one. We only find subviews if we haven&#8217;t already. The only step that is done every time is getting the ViewHolder from the tag and binding data to it. There is a tiny inefficiency left here: when I instantiate the ViewHolder the first time, I push it into the tag and then pull it back out instead of using it directly. I do this intentionally because the overhead required is very tiny and it proves that the system is working immediately. If you have any casting issues with your ViewHolder and View.Tag it&#8217;ll happen the first time a view is created, instead of just when a view is recycled.</p>
<p><em>Note: There are lots of ViewHolder pattern descriptions out there but few (none?) of them use the Initialize/Bind system that I show here. I like this style a lot but I can&#8217;t claim credit for it: <a title="Joel Martinez on code" href="http://codecube.net/" target="_blank">Joel Martinez</a> gave me a lot of ideas here and may be the first to use ViewHolders like this. I just adapted it from Java to Mono.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://syndicatex.com/programming/monodroid-list-optimization/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Construct 2: Kicking the Tires</title>
		<link>http://syndicatex.com/programming/construct-2-kicking-the-tires/</link>
		<comments>http://syndicatex.com/programming/construct-2-kicking-the-tires/#comments</comments>
		<pubDate>Sat, 07 Jan 2012 07:59:50 +0000</pubDate>
		<dc:creator>jjohnson</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[construct2]]></category>
		<category><![CDATA[engines]]></category>
		<category><![CDATA[gamedev]]></category>
		<category><![CDATA[html5]]></category>

		<guid isPermaLink="false">http://syndicatex.com/?p=405</guid>
		<description><![CDATA[I love playing with GameDev tools such as engines, frameworks/libraries, game creators and new languages. I&#8217;ve been a big advocate, fan and user of FlatRedBall for some time as you may know. Today, while reading up on something totally unrelated, I saw a reference to an HTML5 game maker called Creator2. Curious, I read a [...]]]></description>
			<content:encoded><![CDATA[<p><iframe src="http://syndicatex.com/files/c2test/" width="640px" height="600px"></iframe></p>
<p>I love playing with GameDev tools such as engines, frameworks/libraries, game creators and new languages. I&#8217;ve been a big advocate, fan and user of FlatRedBall for some time as you may know.</p>
<p>Today, while reading up on something totally unrelated, I saw a reference to an HTML5 game maker called <a title="Scirra Creator 2" href="http://www.scirra.com/" target="_blank">Creator2</a>. Curious, I read a little about it and decided to play with it this weekend.</p>
<p>I&#8217;ve been pleasantly surprised by how awesome this tool actually is. While I don&#8217;t think it&#8217;s suitable for a super-feature-rich and complex game, it is a pretty solid tool for prototyping or creating casual 2D games. I also was pretty impressed by how smoothly it ran.</p>
<p>I built a tiny but mostly-complete space game in just a few hours. The game features Box2D physics integration, health and scoring. Being able to download the editor, follow a single, short tutorial and immediately create a working prototype is pretty incredible.</p>
]]></content:encoded>
			<wfw:commentRss>http://syndicatex.com/programming/construct-2-kicking-the-tires/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The R word</title>
		<link>http://syndicatex.com/philosophy/the-r-word/</link>
		<comments>http://syndicatex.com/philosophy/the-r-word/#comments</comments>
		<pubDate>Thu, 05 Jan 2012 19:06:05 +0000</pubDate>
		<dc:creator>jjohnson</dc:creator>
				<category><![CDATA[Philosophy]]></category>
		<category><![CDATA[language]]></category>
		<category><![CDATA[professionalism]]></category>
		<category><![CDATA[retard]]></category>
		<category><![CDATA[Rett Syndrome]]></category>

		<guid isPermaLink="false">http://syndicatex.com/?p=399</guid>
		<description><![CDATA[I avoid using strong language. I also try to avoid words that cause offense or harm to specific groups in a professional or public forum. That being said, I generally find jokes that poke fun at racial, religious and other stereotypes funny when they are joking and in the right company or context. As you may [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://syndicatex.com/wp-content/uploads/2012/01/nora_and_i.jpg"><img class="aligncenter size-full wp-image-400" title="nora_and_i" src="http://syndicatex.com/wp-content/uploads/2012/01/nora_and_i.jpg" alt="" width="480" height="444" /></a></p>
<p>I avoid using strong language. I also try to avoid words that cause offense or harm to specific groups in a professional or public forum. That being said, I generally find jokes that poke fun at racial, religious and other stereotypes funny when they <em>are </em>joking and in the right company or context.</p>
<p>As you may know, my beautiful, wonderful, four-year-old daughter <a title="Nora on GirlPower2Cure" href="http://girls.girlpower2cure.org/nora" target="_blank">Nora</a> has a horrible neuro disorder called <a title="Rett Syndrome on Wikipedia" href="http://en.wikipedia.org/wiki/Rett_syndrome" target="_blank">Rett Syndrome</a>. Dealing with Rett Syndrome is a major part of the lives of my family, extended family and friends. When we first found out we were simultaneously crushed by the news and uplifted by the amazing support of our family and friends, that continues to be touching.</p>
<p>My wife and I went to a few meetings that were intended to be a sort of group therapy. We were positive and hopeful but found many of the group members to be bitter, depressed and angry at the world. In one session a parent went off about the use of the word &#8220;retard&#8221; by a large cross-section of people. While I understood the point, my wife and I did not like the anger and bitterness at the world that was a common attitude in the group and quit going.</p>
<p>Words like &#8220;fag&#8221; and &#8220;nigger&#8221; garner a ton of attention because they have an enormous and vocal advocacy group. Professionals that would never use those words on their blogs, twitter or in a public setting are often quick to use the word &#8220;retard,&#8221; which is admittedly surprising to me. The sad thing is, most people that do suffer from some form of mental retardation can&#8217;t defend themselves and thus the word &#8220;retard&#8221; rarely has the backlash that it&#8217;s racial and sexual-orientation counterparts do.</p>
<p>Despite all that, the word rarely bothers me. The internet at large uses it ALL the time. My friends use it frequently. Sometimes my wife and I even slip and use it (we try not to after seeing how offensive it is to some). The word seems to be pretty thoroughly decoupled from its association with disabled individuals. To put it another way, the two offensive words mentioned above still refer to specific groups whereas &#8220;retard&#8221; rarely actually refers to disabled people. Similarly, the words &#8220;stupid&#8221; and &#8220;dumb&#8221; at one time referred to the mentally or physically disabled but now seem to be generally accepted in informal speech. The only time &#8220;retard&#8221; does bother me is when it <em>is </em>used to refer to disabled people, which is highly offensive.</p>
<p>What bothers me more than the R word is the stigma around disabilities &#8211; but who&#8217;s fault is that? It is hard not to look (read: stare) at someone that obviously has a disability. And there&#8217;s nothing wrong with curiosity. I think the stigma is often negatively perpetuated<em> by the caretakers</em> of disabled people when they are rude to people who are curious. In our short-lived support group experience one of the parents ranted about people staring at her child at the park playground and talked about how &#8220;she showed them.&#8221; Of course people are going to stare! They&#8217;re curious and probably afraid to ask if you act like a total jerk because they&#8217;re interested! I&#8217;ve had some really positive experiences with strangers that asked about Nora with genuine concern and a desire to learn about her disability. I also think it&#8217;s awesome when people <a title="Target Ad With Down Syndrome Star" href="http://www.adweek.com/adfreak/boy-down-syndrome-becoming-unlikely-ad-star-137326" target="_blank">treat disabled people like anyone else</a>.</p>
<p>The thing that is absolutely unacceptable is mockery of people with disabilities. I watched a marketing professional, probably in his 30s, make a drunken spectacle of himself at a conference &#8211; impersonating someone with special needs in a public setting. It goes on record as one of the most insulting and pathetic things I&#8217;ve ever seen. So while I may not flinch at the R word, I might get violent at outright mockery or disrespect that&#8217;s actively directed at a disabled person.</p>
<p>Ultimately, if you&#8217;re unfamiliar with the world of disabled people and their caretakers try to treat them like anybody else. Be considerate with your language because it does offend some. If you are a disabled person, caretaker or otherwise related&#8230;focus on the positives: people are fascinated, interested and occasionally legitimately concerned about disabilities. While some of them may be rude, punishing everyone for it only hurts us all.</p>
<p>&nbsp;</p>
<p><em>Note: In case you missed the point, this post is NOT giving you license to say the R word any more than having an African American friend gives you the right to say the N word.</em></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://syndicatex.com/philosophy/the-r-word/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Digital Economics 101</title>
		<link>http://syndicatex.com/philosophy/digital-economics/</link>
		<comments>http://syndicatex.com/philosophy/digital-economics/#comments</comments>
		<pubDate>Wed, 04 Jan 2012 02:18:11 +0000</pubDate>
		<dc:creator>jjohnson</dc:creator>
				<category><![CDATA[Philosophy]]></category>
		<category><![CDATA[economics]]></category>
		<category><![CDATA[gamedev]]></category>
		<category><![CDATA[music]]></category>

		<guid isPermaLink="false">http://syndicatex.com/?p=392</guid>
		<description><![CDATA[As with all of my thoughts, these are hardly original. I have read a bunch of good stuff about economics and the evolution of digital content across the web that got me thinking about these things. But I like to think that I have a knack for reading and understanding the issues, swirling all of [...]]]></description>
			<content:encoded><![CDATA[<p>As with all of my thoughts, these are hardly original. I have read a bunch of good stuff about economics and the evolution of digital content across the web that got me thinking about these things. But I like to think that I have a knack for reading and understanding the issues, swirling all of the ideas around, and spitting out a somewhat cohesive explanation of what it all means without using big fancy words. Incidentally, this has ties to my last post about how <a title="Free services are not free and the Matrix exists" href="http://syndicatex.com/philosophy/the-real-matrix/" target="_blank">&#8220;free&#8221; services aren&#8217;t free</a> so it might be worth reading that too!</p>
<p>&nbsp;</p>
<p>I&#8217;m not an economist but, as far as I know, the main law of economics is the relationship between supply, demand and value. If supply goes down, demand and value go up, etc. Digital content causes problems with this equation because it&#8217;s theoretically infinite. Since the content can be replicated perfectly over and over there is no scarcity of supply and demand can be instantly fulfilled, meaning value is zero. So: infinite supply equals zero value.</p>
<p>I&#8217;ve seen this point argued both ways with people in the middle saying that the supply is not actually infinite and so on. The truth is when you can replicate something as easily and perfectly as you can with anything binary, the supply is practically infinite. I also believe that the law of economics is true, meaning that digital content&#8217;s value goes to near-zero. The preachers-of-doom are right, content has lost its value. Does this mean that good content will die in favor of mass-produced, regurgitated garbage?</p>
<p>&nbsp;</p>
<p>In the late 90s the infamous mp3 caught the music industry by surprise. The way I see it, there were two big catalysts. First, the development of the mp3 compression algorithm (I&#8217;m not sure exactly when this happened and I&#8217;m too lazy to look it up because I&#8217;m a blogger, not a journalist). Second, the steady increase in bandwidth at reasonable prices. Suddenly you could create a 10:1 compressed file of a song, at similar quality, and download it in less than 20 minutes on dialup. When DSL and Cable dropped in price it added fuel to the fire. I&#8217;ll skip the history lesson because you know what happened: Media piracy exploded via P2P networks.</p>
<p>Music, video game, film and other content industries freaked out and are still freaked out because the content they offer is increasingly under valued.</p>
<p>&nbsp;</p>
<p>I felt this burn personally when I created <a title="Get Whirlygig Free Right Now This Minute!" href="http://www.windowsphone.com/en-US/apps/41817089-0da1-e011-986b-78e7d1fa76f8" target="_blank">Whirlygig for WP7</a>. I&#8217;ll readily admit that Whirlygig is not a great game. It&#8217;s not bad, but it&#8217;s not great. And I couldn&#8217;t sell it for a dollar. After working for months on a game, pouring my sweat and soul into something, it was hard to accept that it was worth less than 1/3 of a Starbucks latte. I realized that my hard work had very little perceived value and, at the time, got pretty depressed about the future of indie game dev (which I now find ironic because I consider 2011 to be a pretty stellar year for indies).</p>
<p>I spoke at a mobile marketing conference in Houston in October, 2011 and, as part of my research, I looked at total volume of apps on the market. At the time iTunes had almost 500k apps, Android was nearing 250k and WP7 was working towards 50k for a nice round 800k number. I&#8217;m sure it&#8217;ll hit 1 million total apps soon. So, even without the digital music revolution, the sheer volume of choice makes the perceived value of individual apps very low because supply outweighs demand.</p>
<p>Industry pundits lament the demise of quality content, blah, blah, blah and indies like me either get burned out and quit or continue to do it for the love of it, without hope for financial success. The digital revolution has happened and there is no money to be made in content creation.</p>
<p>Or is there?</p>
<p>&nbsp;</p>
<p>Every equation has inverse equations. If the value of digital content has dropped to zero it is a hard product to sell. But if you think of digital content as a <em>resource </em>and not a <em>product </em>it suddenly has enormous potential because it&#8217;s a FREE RAW MATERIAL.</p>
<p>In 1901 a blacksmith would have to put a moderate amount of labor into creating a tiny metal ring. Now there are factories in China that do nothing but churn thousands of them out a minute. The value of that tiny metal ring has dropped so much that it may as well be valueless. But Victoria Secret combines a few of those metal rings with some lace to create a $35 fancy bra <strong>[1]</strong>. There are two important things happening here. First, Victoria Secret is creating a high-value product from low-value materials. Second, there is artificial scarcity. While all of the materials exist in abundance, the combination is unique, hard to reproduce and thus valuable.</p>
<p>In 2003, <a title="Apple Incorporated" href="http://en.wikipedia.org/wiki/Apple_Inc." target="_blank">some smart company</a> created a way to deliver a product that was dropping in value and create a business around delivering that content. They called their product the iTunes Store and sold individual songs digitally instead of full, physical CDs. Apple took a material that was dropping in value and wrapped it in a unique service that created value. The industrialization of music was becoming complete.</p>
<p>This transition has been further realized by Spotify, Pandora and other streaming services. These services do not sell you songs as a product. You don&#8217;t <em>pay</em> for individual songs at all&#8230;you either pay for a service or even <a title="Not really free" href="http://syndicatex.com/philosophy/the-real-matrix/" target="_blank">get it for free</a> thanks to advertising. The songs are a raw material that powers the service as opposed to a product themselves. These companies have realized that content is getting harder to sell due to the volume available. Additionally, the volume itself creates its own problems that are solved by streaming services. They create playlists and stations of like-music that combine the raw materials (songs) into unique experiences (playlists) just like clasps and fabric in a fancy bra.</p>
<p>Smart game developers have leveraged this. <a title="SpryFox" href="http://www.spryfox.com/" target="_blank">SpryFox</a>&#8216; created Realm of the Mad God (RotMG) and Triple Town, that leverage the exploding Free-To-Play (F2P) business model. In Triple Town you have a limited amount of turns that slowly recharge over time. If you run out of turns you can wait or buy more turns with real money. In RotMG you are limited to a single character at a time unless you buy more slots. You can also pay for cosmetic and other upgrades. League of Legends, TeamFortress 2 and countless other well-known games have similar models. Note that this is very different than in-game ads. In game ads generate some revenue but the model overall is not sustainable long term for any but the highest-downloaded games<strong>[2]</strong>. Additionally, it doesn&#8217;t really view the game as a raw material for a higher-level experience, it&#8217;s just a billboard for a different product that someone else is selling.</p>
<p>So F2P has circumvented the infinite availability by creating a scarcity of supply. You can play TripleTown for free and it&#8217;s a good game (this is a key point, more on this in a bit) but then you run out of supply (turns) <em>after the demand has been generated </em>(when the gamer has been pulled into the game flow). Suddenly the product has value. Even better, it creates a reliable revenue stream for the developer that enables them to add even more content and charge for that too. The game becomes a self-sustaining platform by managing its own supply and demand. But Triple Town&#8217;s model works because it is a good game at its core. The turn threshold is just long enough to get gamers into the flow but short enough that it runs out before you&#8217;re satisfied and the game is good enough that you <em>want </em>to keep going. So, even as I make the point that the value of content is dropping and that content has become a raw material, you have to have GOOD raw material to build a product on top of it. Weak content has no value as a product <em>or </em>a resource.</p>
<p>But I don&#8217;t think these events define the future of the industry. I personally do not like the F2P model in most cases. While I enjoy TripleTown, RotMG, League of Legends and other F2P games, they have gotten a minimum of cash from me (maybe $1). I paid the game price for SWTOR and the monthly fee to play. I also bought Skyrim and often buy indie games on Steam. I like to pay up front or at least know the fixed cost of a media experience. <a title="Indie City: Steam for Indie Games!" href="http://www.indiecity.com" target="_blank">New indie markets</a> are springing up and <a title="Minecraft Creators" href="http://mojang.com/" target="_blank">some indies</a> are making it really big. Some people are content to stream music, pay for a service, and never actually own songs. I prefer to own my collection. Everybody has their own preference: mainstream markets, niche markets, F2P and other evolving models will coexist.</p>
<p>The point is that content creators need to understand the economics of the market. I think we all see and understand the <em>what </em>of the business models that rise around us but do we understand the <em>why </em>of it? Do we know which pie will give us the best exposure and the biggest slice? I discovered this the hard way when I worked hard on Whirlygig and realized that only close friends and fellow devs were really willing to purchase the game<strong>[3] </strong>and mostly out of the goodness of their hearts. The thing I still believe is core to any of these models: you have to create good content. Triple Town&#8217;s model wouldn&#8217;t work if the game didn&#8217;t really suck you in, gamers would hit the barrier and simply walk away. I personally hope to make Whirlygig better and integrate things that will keep people playing and maybe even find a way to make it financially worth it.</p>
<p>We content creators wear a lot of hats as we produce, market and deliver our content. It&#8217;s time to put on your economist hat and find the business model that will earn your shining content the revenue it deserves.</p>
<p>&nbsp;</p>
<p><strong>[1]</strong> I didn&#8217;t use the example of bras to be juvenile, I read about a Chinese factory that does nothing but create the metal rings used in bras in this <a title="Chinese Industrialization" href="http://ngm.nationalgeographic.com/2007/06/instant-cities/hessler-text/1" target="_blank">National Geo Article</a> and have found it fascinating every since.</p>
<p><strong>[2]</strong> Here&#8217;s why ad-supported games are not viable long term:</p>
<ol>
<li>Advertisers (usually brands or retailers) have a product to sell.</li>
<li>Advertisers will never spend more on ads than they make in sales and prefer that cost to be a predictable ratio.</li>
<li>Thus Advertisers prefer to pay for revenue-share on sales (exactly predictable) or clicks (fairly predictable)</li>
<li>Since the Advertiser drives the market they only buy impressions at high volume, for low cost.</li>
<li>New ad markets usually subsidize the impression payouts to get Publishers (developers, website owners, etc) to integrate their ads and have big enough impression blocks to drive deals with Advertisers.</li>
<li>Once the market matures, the Ad Market and Advertisers can forecast sales driven by impressions and stable prices are negotiated</li>
<li>Now that the Ad Market has predictable income they relax the payout subsidies and ad payouts drop for Publishers</li>
<li>The Publisher payout starts as a percentage of the Net Sales price of the Advertiser&#8217;s product and gets further cut by the Ad Market&#8217;s take</li>
</ol>
<p>So, armed with the above knowledge, think about how likely that in-game ad is to actually drive a sale of an Advertiser&#8217;s product. Not likely. Eventually Advertisers will pull out of in-game marketing unless it either drives sales hard or gets really, really cheap. I have purchased ads as an Advertiser long enough to see this happen in several new web markets and I don&#8217;t think mobile will be any different.</p>
<p><strong>[3]</strong> Note that Whirlygig doesn&#8217;t have a trial mode, which probably would have greatly increased the number of purchases. That being said, my research for the Houston talk drove home the point that the conversion rate (conversion rate = purchases / trials) for games is much, much lower than the conversion rates that online retailers and other businesses enjoy. All of the research I have done indicates that it&#8217;s easier to get someone to pay a dollar for a cup of coffee than for an app.</p>
]]></content:encoded>
			<wfw:commentRss>http://syndicatex.com/philosophy/digital-economics/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The Real Matrix</title>
		<link>http://syndicatex.com/philosophy/the-real-matrix/</link>
		<comments>http://syndicatex.com/philosophy/the-real-matrix/#comments</comments>
		<pubDate>Tue, 03 Jan 2012 00:35:58 +0000</pubDate>
		<dc:creator>jjohnson</dc:creator>
				<category><![CDATA[Philosophy]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[dropbox]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[the matrix]]></category>

		<guid isPermaLink="false">http://syndicatex.com/?p=385</guid>
		<description><![CDATA[I read a quote recently (I would credit it if I could remember the source) that was something like: &#8220;If a service is free than YOU are the product.&#8221; Have you seen the movie Wall-E? In many ways, it&#8217;s almost the same story as the Matrix. In the Matrix, humans live in a virtual world [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://syndicatex.com/wp-content/uploads/2012/01/red-pill-blue-pill.jpg"><img class="aligncenter size-full wp-image-386" title="red-pill-blue-pill" src="http://syndicatex.com/wp-content/uploads/2012/01/red-pill-blue-pill.jpg" alt="" width="500" height="568" /></a></p>
<p>I read a quote recently (I would credit it if I could remember the source) that was something like: &#8220;If a service is free than YOU are the product.&#8221;</p>
<p>Have you seen the movie Wall-E? In many ways, it&#8217;s almost the same story as the Matrix.</p>
<p>In the Matrix, humans live in a virtual world where they have the illusion of life and free will. One day Morpheus reveals to Neo that it&#8217;s all a lie. The Earth is a wasteland and robots provide humans with a fake reality to maintain a status quo and keep the humans generating power like a million tiny batteries.</p>
<p>In Wall-E, humans live on a space cruiser where they have the illusion of a happy and relaxing life. One day Wall-E and company reveal to the human race that the Earth is a wasteland and robots provide humans with a fake reality to maintain a status quo.</p>
<p>The main difference is that in Wall-E the robots don&#8217;t seem to get a specific benefit from holding the humans hostage in their fake reality. I consider this to be more of a plot hole than a conscious difference. The other big differences is that Pixar told the story without two terrible sequels (thus far).</p>
<p>Google provides a ton of free, cloud-based services (not a complete list):</p>
<ul>
<li><span style="line-height: 18px;">Search, Personalized Search and Search History (basic Google services)</span></li>
<li><span style="line-height: 18px;">Social Platform (Google Plus)</span></li>
<li><span style="line-height: 18px;">Email (Gmail)</span></li>
<li><span style="line-height: 18px;">Calendar (Google Calendar)</span></li>
<li><span style="line-height: 18px;">Word Processing (Google Docs)</span></li>
<li><span style="line-height: 18px;">Spreadsheets (Google Docs)</span></li>
<li><span style="line-height: 18px;">Presentations (Google Docs)</span></li>
<li><span style="line-height: 18px;">Contacts (Gmail)</span></li>
<li><span style="line-height: 18px;">Chat (gTalk)</span></li>
<li><span style="line-height: 18px;">Web Phone (Google Voice)</span></li>
<li><span style="line-height: 18px;">Mobile Phone OS (Android)</span></li>
<li><span style="line-height: 18px;">Browser (Chrome)</span></li>
<li><span style="line-height: 18px;">Music (Google Music)</span></li>
<li><span style="line-height: 18px;">Affiliate Network (Google Affiliate Network)</span></li>
<li><span style="line-height: 18px;">Checkout Solution (Google Checkout)</span></li>
<li><span style="line-height: 18px;">Analytics (Google Analytics)</span></li>
<li><span style="line-height: 18px;">Photo Hosting (Picasa)</span></li>
<li><span style="line-height: 18px;">Video Hosting (Youtube)</span></li>
<li><span style="line-height: 18px;">Medical Records (Google Health: retired)</span></li>
<li><span style="line-height: 18px;">Miniblogging (Google Buzz: retired)</span></li>
</ul>
<p><span style="line-height: 18px;">Think about how much Google knows about you for each one of those services. The more you use, the more they know. While Google has a pretty stellar track record for keeping personal data secure, they know a LOT about you and they use that to make money. While they may not make money off of your personal data specifically, your information powers their business. In other words, you provide a small amount of electricity that, joined with millions like you, powers the giant robot. Sound familiar? You are Google&#8217;s battery. Google is your fancy space ship, your Matrix.</span></p>
<p>I use Dropbox, Stack Overflow, many of Google services, Facebook, Twitter, Yahoo, Apple, Amazon and probably more that I can&#8217;t even think of. All of these robots provide me a world of convenience, a virtual place where I can store all of the pieces of my life. In return they use that data. The content I generate is used to make their property bigger and draw even more content. My behavior is tracked, logged and used to inject relevant ads in all of my online experiences.</p>
<p>So why do I (or we) do this? Often for the convenience the software provides without a measurable financial impact. But in some cases I&#8217;m not convinced that there is a convenience provided. I recently all but disabled my Facebook account because I realized it doesn&#8217;t offer me any value. If I got on Facebook I would waste time reading mostly-meaningless posts from people I barely know. It wasn&#8217;t providing me a service, it was simply consuming more of my time that I could use to actively communicate with the people that are closest to me. So some services have real value while others have a perceived value that is actually junk entertainment under the guise of communication.</p>
<p>The Matrix and Wall-E both raised these thoughts:</p>
<div>
<ul>
<li>Did the machine provide the experience people want or did it convince people to want the experience it provided?</li>
<li><span style="line-height: normal;">People are inherently lazy. Even when shown the facts, would anybody want to leave?</span></li>
</ul>
</div>
<p>Armed with a belief that the Matrix is a real thing in our world today, it raises more questions:</p>
<div>
<ul>
<li>Does the Cloud, the Social Experience, the Internet-at-large provide the experience that we want; or convince us to want the experience it provides?</li>
<li>If you are under the complete control of an entity but that entity gives you everything you want, is that freedom?</li>
<li>Are we okay with trusting a corporation with every tiny detail of our lives in return for the convenience they provide?</li>
<li>Are these companies even providing us with a convenience or do they simply take our information, our content AND our time?</li>
<li>Ultimately, does anyone want to reclaim their information when it means leaving the convenience of the cloud?</li>
</ul>
<p><span style="line-height: 19px;">The answers to these questions will depend on the reader. The choice is yours, Neo. Red pill or blue?</span></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://syndicatex.com/philosophy/the-real-matrix/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Load Remote Content in FlatRedBall</title>
		<link>http://syndicatex.com/flatredball/flatredball-remote-content/</link>
		<comments>http://syndicatex.com/flatredball/flatredball-remote-content/#comments</comments>
		<pubDate>Thu, 22 Dec 2011 17:56:46 +0000</pubDate>
		<dc:creator>jjohnson</dc:creator>
				<category><![CDATA[FlatRedBall]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Resource Loading]]></category>
		<category><![CDATA[Sprites]]></category>

		<guid isPermaLink="false">http://syndicatex.com/?p=380</guid>
		<description><![CDATA[Long ago I wrote a small and crappy top-scroller in AS3 that loaded all of its content from XML. The idea was that somebody could create their own graphics and XML to basically define all game assets and levels. It was rudimentary but it worked and I still like the idea of a game that [...]]]></description>
			<content:encoded><![CDATA[<p>Long ago I wrote a small and crappy top-scroller in AS3 that loaded all of its content from XML. The idea was that somebody could create their own graphics and XML to basically define all game assets and levels. It was rudimentary but it worked and I still like the idea of a game that loads all of its resources from remote sources.</p>
<p>So, how would you go about this in my <a title="Free 2.5d game engine" href="http://www.flatredball.com" target="_blank">favorite game engine</a>?</p>
<p>I&#8217;m glad you asked. Here&#8217;s a quick and dirty description of how you can load sprites from remote sources in FlatRedBall. You could extend this concept to load CSV data and create generic Entities that populate their properties and sprite representations from remote resources. This assumes that you know your way around FlatRedBall to some extent, at least how to create an Entity in Glue and then add some custom code in Visual Studio [Express].</p>
<p>First we need a data loading class. This is pretty basic but note that I&#8217;m copying the ResponseStream into a MemoryStream. This is because creating a Texture2D from a Stream requires the Stream to be seekable. So, this is a pretty-efficient way to do that but if someone knows a better way I&#8217;d love to hear it in the comments.</p>
<pre class="brush:csharp">using System;
using System.IO;
using System.Net;

namespace RemoteExample.Data {
    public static class Loader {

        public static MemoryStream GetResource(Uri uri) {
            try {
                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                using (Stream responseStream = response.GetResponseStream()) {
                    MemoryStream seekableStream = new MemoryStream();
                    responseStream.CopyTo(seekableStream);
                    return seekableStream;
                }
            }
            catch (Exception e) {
                Console.WriteLine("GetResource failed: " + e.Message);
                return null;
            }
        }
    }
}</pre>
<p>&nbsp;</p>
<p>Now we need to turn a resource URI into a Texture2D and apply that texture to a Sprite. Here&#8217;s our texture:</p>
<p><a href="http://syndicatex.com/wp-content/uploads/2011/12/scout_green.png"><img title="scout_green" src="http://syndicatex.com/wp-content/uploads/2011/12/scout_green.png" alt="" width="16" height="16" /></a></p>
<p>&nbsp;</p>
<p>And here&#8217;s a very-simple way to load it up, using our Data.Loader class (obviously you&#8217;d want to make this more flexible, handle a null return, etc):</p>
<pre class="brush:csharp">using System;
using FlatRedBall;
using Texture2D = Microsoft.Xna.Framework.Graphics.Texture2D;
using RemoteExample.Data;

namespace RemoteExample.Entities
{
    public partial class Ship
    {
        Sprite ShipSprite;

        private void CustomInitialize()
        {
            // quick and dirty, for demo only!
            Uri spriteUri = new Uri(@"http://syndicatex.com/wp-content/uploads/2011/12/scout_green.png");
            System.IO.Stream spriteStream = Loader.GetResource(spriteUri);
            Texture2D spriteTexture = Texture2D.FromStream(FlatRedBallServices.GraphicsDevice, spriteStream);
            ShipSprite = new Sprite();
            ShipSprite.Texture = spriteTexture;
            SpriteManager.AddSprite(ShipSprite);
            ShipSprite.AttachTo(this, false);
        }

        // collapsed for brevity
        private void CustomActivity() { }
        private void CustomDestroy() { }
        private static void CustomLoadStaticContent(string contentManagerName) { }
    }
}</pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><strong>HOMEWORK:</strong> <em>Push the loading of textures into another thread and display a local, generic sprite until the resource loads. Use Thread.Sleep(10000) at the beginning of the Data.Load.GetResource() method to test it!</em></p>
]]></content:encoded>
			<wfw:commentRss>http://syndicatex.com/flatredball/flatredball-remote-content/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Understanding Threading and Why Android Feels Sluggish</title>
		<link>http://syndicatex.com/programming/understanding-threading-and-why-android-feels-sluggish/</link>
		<comments>http://syndicatex.com/programming/understanding-threading-and-why-android-feels-sluggish/#comments</comments>
		<pubDate>Thu, 08 Dec 2011 23:14:46 +0000</pubDate>
		<dc:creator>jjohnson</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://syndicatex.com/?p=377</guid>
		<description><![CDATA[User Interface Performance: Why it Matters Fact: All but the most hardcore Android fanboys agree that even the best devices feel laggy compared to the snappy iOS UI. This is not speculation or a debatable point. If you believe that the Android User Interface (UI) is as consistently responsive as the iOS UI, you are [...]]]></description>
			<content:encoded><![CDATA[<p><strong>User Interface Performance: Why it Matters</strong></p>
<p>Fact: All but the most hardcore Android fanboys agree that even the best devices feel laggy compared to the snappy iOS UI.</p>
<p>This is not speculation or a debatable point. If you believe that the Android User Interface (UI) is as consistently responsive as the iOS UI, you are simply incorrect. It&#8217;s SCIENCE! There are specific reasons for this which I&#8217;m about to discuss but first let&#8217;s talk about why a laggy UI is a problem.</p>
<p>UI stands for User Interface but it may as well stand for User Experience. For most users, if their desktop computer does not immediately respond to user input their computer is &#8220;running slow.&#8221; It doesn&#8217;t matter what the cause is or how fast the hardware is actually running in the background. If it <em>feels </em>slow, it <em>is </em>slow. This is even more important with a touch screen device. If the user&#8217;s browser renders a page slowly, the &#8220;internet is slow&#8221; even if all of the resources are loaded. The point here is, if the UI is sluggish the entire experience suffers.</p>
<p>A mouse is an abstraction of the on-screen cursor, which differs from everything else in the physical world. When you push a toy car or interact with anything else in the physical world, it moves instantly. Picturing a car moving slower than it&#8217;s being pushed doesn&#8217;t even make sense to our brain because it&#8217;s physically impossible in the real world. It&#8217;s hard to even describe that concept with words. When you work a mouse, a cursor moves on the screen and, hopefully, it feels like the two are connected but you&#8217;re not actually manipulating the cursor. It&#8217;s different than physical interaction.</p>
<p>Touch devices are unique in that they can actually make you feel like you are manipulating physical objects even though they exist in a virtual space. The moment you introduce response latency the illusion of physical interaction shatters and suddenly you&#8217;re just using another electronic device. This is why iDevices feel magic (most of the time). It&#8217;s also, in my opinion, why Android is still behind the curve despite making advances that actually trump the iOS in many, many areas.</p>
<p>&nbsp;</p>
<p><strong>Understanding Threading</strong></p>
<p>Let&#8217;s say you have a todo list with two items that <em>must be done sequentially</em>:</p>
<ul>
<li><span style="line-height: 18px;">Get Mail</span></li>
<li><span style="line-height: 18px;">Do Dishes</span></li>
</ul>
<p>You have to wait for the mail <em>before </em>you can start doing the dishes. This is wasteful as you could do the dishes while you&#8217;re waiting for the mail to arrive. Getting the mail does not require effort until the mail arrives.</p>
<p>This is a common problem in programming. An application is just a collection of tasks. Some tasks, such as making network requests, take time but don&#8217;t require actual effort by the processor. So waiting for them is wasteful. To solve this, you can create multiple &#8220;threads&#8221; in an application. One thread could be created to do something with the mail and another thread to do the dishes. A CPU core in a computer can only do a single thing at once but since waiting doesn&#8217;t require effort it can process the &#8220;Do Dishes&#8221; request while waiting for a response from &#8220;Get Mail.&#8221; Threads can also be given different priorities. Maybe there are important bills in the mail. If you give the &#8220;Get Mail&#8221; thread top priority than the dishes thread would immediately be paused when there was mail to fetch.</p>
<p>This directly applies to User Interface. Traditionally, User Interface tasks (handling input and rendering to the screen) were assigned to one thread and other tasks (requesting data from the network, etc) were given other threads. But the User Interface doesn&#8217;t get any special priority. A computer is designed to do many things at once and you wouldn&#8217;t want a web page to stop loading while you clicked the mouse or a window was being rendered.</p>
<p>&nbsp;</p>
<p><strong>UI Threading: Android vs iOS</strong></p>
<p>When Android was first developed the UI was created to compete with Blackberry and other phones at the time. Development on Android started prior to iPhone and followed the traditional UI model. The UI Thread in Android runs at standard priority.</p>
<p>When iOS was developed they did not follow this model. The UI Thread on iPhones, iPods and iPads actually gets &#8220;realtime&#8221; priority, meaning it trumps almost everything (over-simplified to illustrate the point)<em>. </em>Other processes are blocked until the UI Thread has completed processing and you&#8217;re not allowing it to finish.</p>
<p>This iOS convention can probably be broken in code by a naive developer but the point is that the design of the iOS to work like that from the start also bred that tendency into iOS developers&#8230;to prioritize snappy UI response from the beginning.</p>
<p>Since iOS was developed this has become a standard in mobile development (I believe that WP7 works this way too) but there are some major barriers to changing the way it works in Android. Ultimately, better hardware utilization and multi-core processors in mobile devices will improve the perceived response but, unless there are some major changes, the Android OS as a whole will continue to be slower than it&#8217;s Apple counterparts.</p>
<p>While there are other factors such as hardware acceleration, garbage collection and Dalvik maturity, the threading system is core to the problem.</p>
<p>&nbsp;</p>
<p><strong>Finally</strong></p>
<p>Despite Android&#8217;s impressive advances, I am of the opinion that the UI response will continue to be a barrier that affects customer perception (and thus adoption over Apple). No matter how sleek and shiny Android devices get, there will be a perceptual black mark on their record for the UI performance until it&#8217;s as fast as iOS.</p>
<p>All of this information comes from these articles which were very interesting but long, spread out and hard to explain to non-developers. I felt like it was worth summarizing these two long reads into a more simple, layman&#8217;s overview of the differences between the two mobile operating systems&#8217; UI. I hope it was worth reading.</p>
<p><a href="https://plus.google.com/u/0/105051985738280261832/posts/2FXDCz8x93s" target="_blank">Android Graphic Facts</a></p>
<p><a href="https://plus.google.com/u/0/100838276097451809262/posts/VDkV9XaJRGS" target="_blank">Android Graphic Facts Followup</a></p>
<p>&nbsp;</p>
<p>Another good resource regarding Android performance (old but still relevant):</p>
<p><a href="http://www.google.com/events/io/2009/sessions/TurboChargeUiAndroidFast.html" target="_blank">Developing Responsive UI in Android</a></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://syndicatex.com/programming/understanding-threading-and-why-android-feels-sluggish/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Best Practice: Passing Types to Methods</title>
		<link>http://syndicatex.com/programming/passing-types-to-method/</link>
		<comments>http://syndicatex.com/programming/passing-types-to-method/#comments</comments>
		<pubDate>Fri, 02 Dec 2011 21:00:29 +0000</pubDate>
		<dc:creator>jjohnson</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[mono]]></category>

		<guid isPermaLink="false">http://syndicatex.com/?p=375</guid>
		<description><![CDATA[Here&#8217;s a question that maybe a C# Guru can weigh in on&#8230; I abstracted some Activity-launching code that I use everywhere into a method on the base Activity that all of my Activities inherit from: protected void LaunchActivity&#60;T&#62;(string url) { Intent activity = new Intent(this, typeof(T)); if (url != null) { activity.PutExtra("ApiUrl", url); } StartActivity(activity); [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a question that maybe a C# Guru can weigh in on&#8230;</p>
<p>I abstracted some Activity-launching code that I use everywhere into a method on the base Activity that all of my Activities inherit from:</p>
<pre class="brush:csharp">protected void LaunchActivity&lt;T&gt;(string url) {
    Intent activity = new Intent(this, typeof(T));
    if (url != null) {
        activity.PutExtra("ApiUrl", url);
    }
    StartActivity(activity);
}

// makes starting activities really easy:
LaunchActivity&lt;MyActivityType&gt;("http://myApiUrl.com");</pre>
<p>&nbsp;</p>
<p>I think this method could also be defined like this:</p>
<pre class="brush:csharp">protected void LaunchActivity(Type t, string url) {
    Intent activity = new Intent(this, t);
    if (url != null) {
        activity.PutExtra("ApiUrl", url);
    }
    StartActivity(activity);
}

// now you have to use typeof() in the method call every time:
LaunchActivity(typeof(MyActivityType), "http://myApiUrl.com");</pre>
<p>&nbsp;</p>
<p>I picked the first one purely because I didn&#8217;t want to do typeof() in every method call. Are they the same thing or is one superior?</p>
]]></content:encoded>
			<wfw:commentRss>http://syndicatex.com/programming/passing-types-to-method/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

