<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[InfoSpace Technology Blog]]></title>
  <link href="http://tech.infospace.com/atom.xml" rel="self"/>
  <link href="http://tech.infospace.com/"/>
  <updated>2016-08-10T17:49:06+00:00</updated>
  <id>http://tech.infospace.com/</id>
  <author>
    <name><![CDATA[InfoSpace Holdings LLC]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[InfoSpace AWS Case Study]]></title>
    <link href="http://tech.infospace.com/2013/11/12/infospace-aws-case-study/"/>
    <updated>2013-11-12T09:18:00+00:00</updated>
    <id>http://tech.infospace.com/2013/11/12/infospace-aws-case-study</id>
    <content type="html"><![CDATA[<p><a href="http://aws.amazon.com">Amazon Web Services</a> released a detailed case study based on our recent migration of InfoSpace&rsquo;s search application to AWS. Key takeaways from the case study include:</p>

<ul>
<li>Multi-region cloud presence</li>
<li>Microsoft .Net stack</li>
<li>6 month migration &ndash; during which traffic increased by 30%</li>
<li>20% improvement in international response times (10% domestic)</li>
<li>Reduced capital budget by 32%</li>
</ul>


<p>You can read all about it <a href="http://aws.amazon.com/solutions/case-studies/infospace/">here</a>. We are planning to write a series on this blog detailing our cloud migration, so stay tuned.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Feedly OAuth2 Authentication Workflow in Android]]></title>
    <link href="http://tech.infospace.com/2013/10/24/feedly-oauth2-authentication-in-android-using-a-webview/"/>
    <updated>2013-10-24T15:54:00+00:00</updated>
    <id>http://tech.infospace.com/2013/10/24/feedly-oauth2-authentication-in-android-using-a-webview</id>
    <content type="html"><![CDATA[<p>Android<sup>tm</sup> supports the ability for users to pass OAuth2 credentials stored on their device straight to Google<sup>tm</sup> Services (as documented here: <a href="http://developer.android.com/google/play-services/auth.html">http://developer.android.com/google/play-services/auth.html</a>).  But let&rsquo;s say you want to authenticate against a non-Google service such as Feedly (<a href="http://developer.feedly.com">http://developer.feedly.com</a>) using your Google account credentials.</p>

<p>Google does not permit the OAuth2 Access Tokens stored on your device to be sent to anyone besides a Google Service.  From a security standpoint this is exactly what the user wants, otherwise a malicious app could hijack the users Google OAuth2 token.  We want to avoid situations where the user entering Google credentials on a non-Google controlled environment.</p>

<p>So what is the appropriate workflow for a service which wishes to utilize Google purely as an authentication mechanism?  Feedly looks something like this:</p>

<ul>
<li>User makes login request to Feedly</li>
<li>Feedly responds with an authentication url &ndash; this is controlled and generated by Google</li>
<li>User browses to authentication url</li>
<li>User submits credentials</li>
<li>Google validates credentials

<ul>
<li>If valid, Google notifies Feedly and redirects User to a new URL with a special short lived code generated by Feedly</li>
<li>If not valid, user can attempt authentication again</li>
</ul>
</li>
<li>Once validated, Feedly Local Client retrieves code from URL</li>
<li>Feedly Local Client uses code against Service to obtain a refresh token and access token</li>
</ul>


<p>At this point the user is validated against the Google OAuth2 credentials.  The client app consuming the 3rd party service (feedly) can be reasonably certain the person logged in should have access to the login information.  Because of this, the client app should be permitted to make API calls against the 3rd party service call utilizing the access token.  Again, since the access token was generated based on a successful OAuth2 authentication against the user&rsquo;s Google account, we can be reasonably confident that any requests made with the access token can be made on behalf of the previously authenticated OAuth2 account.</p>

<p>On a web/mobile web app the login process will look fairly seamless.  Basically a series of quick redirects with some pauses in the workflow for user login input.</p>

<p>On a native Android application, an HTTP request running asynchronously in the background cannot be used from start to finish since at some point the user must enter credentials in the Google Authentication URL webpage.  To do this we must embed a <code>WebView</code> within the application.</p>

<p>We recently went through the exercise of putting together a proof-of-concept Android application which leveraged the Feedly API.  While doing so we noticed the Authentication piece is fairly boilerplate code and follows the workflow of many other OAuth2-exposed APIs.</p>

<p>If you wish to view our implementation or use it in your Android application as a Library project the code is accessible here:</p>

<p><a href="https://github.com/infospace/android_oauth2_webview">https://github.com/infospace/android_oauth2_webview</a></p>

<p>As we want to provide a high level of device coverage, we used the compatibility library fragments.  There is even a framework in place to create calls to the various Feedly API methods.  See <code>com.infospace.feedly.requests.RetrieveSubscriptionsRequests.java</code> in the github repo for reference if you wish to look into creating more Feedly API requests.</p>

<p>Simply import the Android library project to integrate it with your existing Fragment-based Android project.  When you wish to display the authentication portion, all you have to do is initialize some helper classes on activity start, and then push the fragment.  Once the user authenticates the fragment automatically saves the refresh/access tokens for further use within the application.</p>

<p>If you have any questions please leave a comment!</p>

<p><em>Android and Google are trademarks of Google Inc.</em></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Building For Multiple Screens]]></title>
    <link href="http://tech.infospace.com/2013/10/18/building-for-multiple-screens/"/>
    <updated>2013-10-18T12:33:00+00:00</updated>
    <id>http://tech.infospace.com/2013/10/18/building-for-multiple-screens</id>
    <content type="html"><![CDATA[<p>I recently presented a talk on <a href="http://www.bigandroidbbq.com/paul-oremland-building-for-multiple-screens/">Building For Multiple Screens</a> at the <a href="http://www.bigandroidbbq.com/">Big Android BBQ</a> with the goal of bridging the gap between the concepts and theory behind building for multiple screens and practice of building for multiple screens. The talk was received well and I thought it would be helpful to turn it into a blog post.</p>

<p>There are three main things that, if you pay attention to, will help you build your app so that it scales and feels natural on a variety of screen sizes.</p>

<ul>
<li>Planning and understanding your application workflow and navigation.</li>
<li>Creating layouts for your workflow that allow you to take full advantage of multiple screen sizes.</li>
<li>Implement your application workflow using and taking advantage of the idioms built in to Android<sup>TM</sup>.</li>
</ul>


<p>This post isn&rsquo;t going to go into any depth on the first two, but if you&rsquo;re interested I&rsquo;ve <a href="https://github.com/poremland/babbq13_presentation">posted my presentation</a> as well as a <a href="https://github.com/poremland/android_rss_reader">sample RSS Reader application</a> which will help walk you through the concepts.</p>

<h2>The Workflow</h2>

<p>One of the most common workflows I see people asking for help with is the multi-pane workflow. A typical example of this workflow is when you start with a list, tap on a row in the list, and get additional content related to the row you initially clicked on.</p>

<p>On a phone we&rsquo;d expect tapping on the row to navigate us to another screen with the additional data. On a tablet, where we have a lot more room for content, we have the expectation of being able to keep the context of our original list while also viewing the additional data about the row we selected.</p>

<p><img src="http://tech.infospace.com/images/building-for-multiple-screens/dual_pane.png"></p>

<!--more-->


<h2>The Layouts</h2>

<p>For the purpose of this post we&rsquo;re going to focus on two layouts.</p>

<p><sub><strong>default/phone:</strong> <code>res/layout/main.xml</code></sub></p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;</span>
</span><span class='line'><span class="nt">&lt;LinearLayout</span>
</span><span class='line'>    <span class="na">xmlns:android=</span><span class="s">&quot;http://schemas.android.com/apk/res/android&quot;</span>
</span><span class='line'>    <span class="na">android:id=</span><span class="s">&quot;@+id/fragment_container&quot;</span>
</span><span class='line'>    <span class="na">android:orientation=</span><span class="s">&quot;vertical&quot;</span>
</span><span class='line'>    <span class="na">android:layout_width=</span><span class="s">&quot;match_parent&quot;</span>
</span><span class='line'>    <span class="na">android:layout_height=</span><span class="s">&quot;match_parent&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>
</span><span class='line'>    <span class="c">&lt;!-- No Fragments defined --&gt;</span>
</span><span class='line'>
</span><span class='line'><span class="nt">&lt;/LinearLayout&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p><sub><strong>tablets:</strong> <code>res/layout-large/main.xml</code> and/or <code>res/layout-sw600dp/main.xml</code></sub></p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;</span>
</span><span class='line'><span class="nt">&lt;LinearLayout</span>
</span><span class='line'>    <span class="na">xmlns:android=</span><span class="s">&quot;http://schemas.android.com/apk/res/android&quot;</span>
</span><span class='line'>    <span class="na">android:id=</span><span class="s">&quot;@+id/fragment_container&quot;</span>
</span><span class='line'>    <span class="na">android:orientation=</span><span class="s">&quot;horizontal&quot;</span>
</span><span class='line'>    <span class="na">android:layout_width=</span><span class="s">&quot;match_parent&quot;</span>
</span><span class='line'>    <span class="na">android:layout_height=</span><span class="s">&quot;match_parent&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>    <span class="nt">&lt;Fragment</span>
</span><span class='line'>        <span class="na">android:name=</span><span class="s">&quot;your.package.FirstFragment&quot;</span>
</span><span class='line'>        <span class="na">android:id=</span><span class="s">&quot;@+id/first_fragment&quot;</span>
</span><span class='line'>        <span class="na">android:layout_weight=</span><span class="s">&quot;1&quot;</span>
</span><span class='line'>        <span class="na">android:layout_width=</span><span class="s">&quot;0dp&quot;</span>
</span><span class='line'>        <span class="na">android:layout_height=</span><span class="s">&quot;match_parent&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>    <span class="nt">&lt;Fragment</span>
</span><span class='line'>        <span class="na">android:name=</span><span class="s">&quot;your.package.SecondFragment&quot;</span>
</span><span class='line'>        <span class="na">android:id=</span><span class="s">&quot;@+id/second_fragment&quot;</span>
</span><span class='line'>        <span class="na">android:layout_width=</span><span class="s">&quot;0dp&quot;</span>
</span><span class='line'>        <span class="na">android:layout_height=</span><span class="s">&quot;match_parent&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'><span class="nt">&lt;/LinearLayout&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>The layouts are both for the same activity. Again, I won&rsquo;t go into details about the layout other than to show you the XML and call attention to one important point.</p>

<p>Notice that the first layout doesn&rsquo;t include any fragments while the second one does. The reason is that for the default/phone workflow we simply want to replace the current fragment on screen with a new one or a previous one as we navigate through the content.</p>

<p>Fragments that are declared in the XML layout file cannot be programmatically replaced using a FragmentTransaction. Only fragments added via a FragmentTransaction can be replaced. Instead you have to programmatically show/hide Fragments declared in a layout.  We&rsquo;ll handle this in the code below but I wanted to call attention to it as it helps provide some context for the code we&rsquo;re about to dive into.</p>

<h2>Handling The Activity Life-Cycle</h2>

<h2><sub>Activity start-up</sub></h2>

<p>The first thing we want to look at is what we do when the activity starts up.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="nd">@Override</span>
</span><span class='line'><span class="kd">public</span> <span class="kt">void</span> <span class="nf">onCreate</span><span class="o">(</span><span class="n">Bundle</span> <span class="n">savedInstanceState</span><span class="o">)</span>
</span><span class='line'><span class="o">{</span>
</span><span class='line'>  <span class="kd">super</span><span class="o">.</span><span class="na">onCreate</span><span class="o">(</span><span class="n">savedInstanceState</span><span class="o">);</span>
</span><span class='line'>  <span class="n">setContentView</span><span class="o">(</span><span class="n">R</span><span class="o">.</span><span class="na">layout</span><span class="o">.</span><span class="na">main</span><span class="o">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">if</span><span class="o">(</span><span class="n">savedInstanceState</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span>
</span><span class='line'>  <span class="o">{</span>
</span><span class='line'>      <span class="k">this</span><span class="o">.</span><span class="na">displayFragment</span><span class="o">(</span><span class="n">R</span><span class="o">.</span><span class="na">id</span><span class="o">.</span><span class="na">first_fragment</span><span class="o">);</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Notice that because we’ve used the built-in configuration qualifier idioms we only have to reference <code>R.layout.main</code> in the call to <code>setContentView</code> and Android<sup>TM</sup> will chose the correct layout for us automatically.</p>

<p>We also want to make sure that we don&rsquo;t go through all the work of setting up our fragment if we&rsquo;re just resuming from the background. So we put in a quick check to see if we&rsquo;re being passed any saved state.</p>

<h2><sub>Displaying a Fragment</sub></h2>

<p>You may have noticed that there appears to be a lot of <em>magic</em> in the <code>onCreate</code> method because it just calls <code>displayFragment</code>. Let&rsquo;s de-mystify that magic and show you what&rsquo;s really going on when we call <code>displayFragment</code>.</p>

<p>The first thing <code>displayFragment</code> does is check to see if our fragment already exists in our layout. We&rsquo;ll get to the inner workings of what <code>getFragment</code> is doing in just a minute, but it&rsquo;s important to understand why we need to try to get a handle to the fragment if it exists.</p>

<p>Remember that our default/phone workflow did not define any fragments in the layout. Only our layout for larger screens defines the fragments in the layout. This is useful to us in code as having a non-null fragment is our queue that we need to update the fragments content and not push a new fragment onto the screen. In other words, it&rsquo;s our primary technique to respond to our workflow without having to hard code each possible workflow scenario into our code.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="kd">public</span> <span class="kt">void</span> <span class="nf">displayFragment</span><span class="o">(</span><span class="kt">int</span> <span class="n">id</span><span class="o">)</span>
</span><span class='line'><span class="o">{</span>
</span><span class='line'>  <span class="n">Fragment</span> <span class="n">fragment</span> <span class="o">=</span> <span class="k">this</span><span class="o">.</span><span class="na">getFragment</span><span class="o">(</span><span class="n">id</span><span class="o">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// the fragment is null if it&#39;s not already being displayed</span>
</span><span class='line'>  <span class="c1">// or it&#39;s been declared in the currently displayed layout</span>
</span><span class='line'>  <span class="k">if</span><span class="o">(</span><span class="n">fragment</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span>
</span><span class='line'>  <span class="o">{</span>
</span><span class='line'>      <span class="n">fragment</span> <span class="o">=</span> <span class="k">this</span><span class="o">.</span><span class="na">createFragment</span><span class="o">(</span><span class="n">id</span><span class="o">);</span>
</span><span class='line'>      <span class="k">this</span><span class="o">.</span><span class="na">addFragmentToBackStack</span><span class="o">(</span><span class="n">fragment</span><span class="o">,</span> <span class="n">id</span><span class="o">);</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'>  <span class="k">else</span>
</span><span class='line'>  <span class="o">{</span>
</span><span class='line'>      <span class="n">fragment</span><span class="o">.</span><span class="na">loadData</span><span class="o">();</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<h2><sub>Checking to see if a fragment exists</sub></h2>

<p>When defining a fragment in a layout you give the fragment an id using the <code>android:id</code> attribute and (optionally) a tag using the <code>android:tag</code> attribute on the <code>&lt;Fragment&gt;</code> element.</p>

<p>My preference is to only define the <code>android:id</code> and then when I push fragments using a transaction I use the <code>R.id.YOUR_FRAGMENT_ID</code> value as the tag (converted as a string).  This allows us to simplify checking for the fragment as we&rsquo;ve done in our <code>getFragment</code> method.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="kd">public</span> <span class="kt">void</span> <span class="nf">getFragment</span><span class="o">(</span><span class="kt">int</span> <span class="n">id</span><span class="o">)</span>
</span><span class='line'><span class="o">{</span>
</span><span class='line'>  <span class="n">FragmentManager</span> <span class="n">manager</span> <span class="o">=</span> <span class="n">getSupportFragmentManager</span><span class="o">();</span>
</span><span class='line'>  <span class="n">Fragment</span> <span class="n">fragment</span> <span class="o">=</span> <span class="n">manager</span><span class="o">.</span><span class="na">findFragmentByTag</span><span class="o">(</span><span class="n">Integer</span><span class="o">.</span><span class="na">toString</span><span class="o">(</span><span class="n">id</span><span class="o">));</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">if</span><span class="o">(</span><span class="n">fragment</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span>
</span><span class='line'>  <span class="o">{</span>
</span><span class='line'>      <span class="n">fragment</span> <span class="o">=</span> <span class="n">manager</span><span class="o">.</span><span class="na">findFragmentById</span><span class="o">(</span><span class="n">id</span><span class="o">);</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'>  <span class="k">return</span> <span class="n">fragment</span><span class="o">;</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<h2><sub>Adding a fragment to the back stack</sub></h2>

<p>In the case that <code>getFragment</code> returns null for the fragment we asked for; We need to create an instance of the fragment and then, using a fragment transaction, push the fragment to the screen by adding it to the back stack.</p>

<p>Adding a fragment to the back stack allows Android<sup>TM</sup> to automatically undo the transaction when the user clicks the back button.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="kd">public</span> <span class="kt">void</span> <span class="nf">addFragmentToBackStack</span><span class="o">(</span><span class="n">Fragment</span> <span class="n">fragment</span><span class="o">,</span> <span class="kt">int</span> <span class="n">id</span><span class="o">)</span>
</span><span class='line'><span class="o">{</span>
</span><span class='line'>  <span class="n">FragmentManager</span> <span class="n">manager</span> <span class="o">=</span> <span class="n">getSupportFragmentManager</span><span class="o">();</span>
</span><span class='line'>  <span class="k">if</span><span class="o">(</span><span class="n">fragment</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">&amp;&amp;</span> <span class="n">manager</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">fragment</span><span class="o">.</span><span class="na">isInLayout</span><span class="o">())</span>
</span><span class='line'>  <span class="o">{</span>
</span><span class='line'>      <span class="n">FragmentTransaction</span> <span class="n">transaction</span> <span class="o">=</span> <span class="n">manager</span><span class="o">.</span><span class="na">beginTransaction</span><span class="o">();</span>
</span><span class='line'>      <span class="c1">// perform any custom fragment workflows here.</span>
</span><span class='line'>      <span class="c1">// like hiding/showing fragments declared in the layout</span>
</span><span class='line'>      <span class="c1">// using transaction.hide(...) or transaction.show(../)</span>
</span><span class='line'>      <span class="n">transaction</span><span class="o">.</span><span class="na">replace</span><span class="o">(</span><span class="n">R</span><span class="o">.</span><span class="na">id</span><span class="o">.</span><span class="na">fragment_container</span><span class="o">,</span> <span class="n">fragment</span><span class="o">,</span> <span class="n">Integer</span><span class="o">.</span><span class="na">toString</span><span class="o">(</span><span class="n">id</span><span class="o">));</span>
</span><span class='line'>      <span class="n">transaction</span><span class="o">.</span><span class="na">addToBackStack</span><span class="o">(</span><span class="kc">null</span><span class="o">);</span>
</span><span class='line'>      <span class="n">transaction</span><span class="o">.</span><span class="na">commit</span><span class="o">();</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<h2><sub>Popping the back stack</sub></h2>

<p>Because we&rsquo;ve added the transaction to the back stack we don&rsquo;t <em>have</em> to do any additional work for the hard/soft back buttons to work correctly but in practice there is a little work we need to do.</p>

<p>In the case that your application is using an ActionBar you&rsquo;re going to need to invalidate the options menu when popping items so that any options that have been added by the fragment that was displayed are removed.</p>

<p>We also need to update the home button if we&rsquo;re using an ActionBar to ensure that the home button provides the correct visual feedback to the user.</p>

<p>I also like to track, in the method, whether or not we actually popped something and return that value.  The reason is that I believe the user has an expectation that the app will close when mashing the back button, but not when mashing the home button in the action bar.  So in the case of the back button we&rsquo;re going to want to call <code>finish</code> on our activity if no back stack was popped, whereas for the home button we wouldn&rsquo;t do anything.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="kd">private</span> <span class="kt">boolean</span> <span class="nf">popBackStack</span><span class="o">()</span>
</span><span class='line'><span class="o">{</span>
</span><span class='line'>  <span class="kt">boolean</span> <span class="n">wasBackStackPopped</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span>
</span><span class='line'>  <span class="n">FragmentManager</span> <span class="n">manager</span> <span class="o">=</span> <span class="n">getSupportFragmentManager</span><span class="o">();</span>
</span><span class='line'>  <span class="k">if</span><span class="o">(</span><span class="n">manager</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span>
</span><span class='line'>  <span class="o">{</span>
</span><span class='line'>      <span class="k">if</span><span class="o">(</span><span class="k">this</span><span class="o">.</span><span class="na">shouldPopBackStack</span><span class="o">(</span><span class="n">manager</span><span class="o">))</span>
</span><span class='line'>      <span class="o">{</span>
</span><span class='line'>          <span class="n">manager</span><span class="o">.</span><span class="na">popBackStack</span><span class="o">();</span>
</span><span class='line'>          <span class="n">wasBackStackPopped</span> <span class="o">=</span> <span class="kc">true</span><span class="o">;</span>
</span><span class='line'>      <span class="o">}</span>
</span><span class='line'>      <span class="k">this</span><span class="o">.</span><span class="na">invalidateOptionsMenu</span><span class="o">();</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">this</span><span class="o">.</span><span class="na">updateHomeButton</span><span class="o">();</span>
</span><span class='line'>  <span class="k">return</span> <span class="n">wasBackStackPopped</span><span class="o">;</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>The <code>shouldPopBackStack</code> and <code>updateHomeButton</code> methods need to contain the custom logic, which is specific to your apps workflow, to decide if something in the back stack should be popped and what type of visual feedback to provide.  In the case of a dual-pane app we wouldn&rsquo;t want to pop the back stack or show the back arrow on the home button if the only two fragments that are displayed are the original two fragments defined in the layout file.</p>

<h2>Wrapping it all up</h2>

<p>Building for multiple screens doesn&rsquo;t require much additional work once you understand the tools at your disposal. The only requirements are:</p>

<ul>
<li>Understanding the workflow and navigation of your app in order to identify opportunities for customized layouts.</li>
<li>Creating the custom layouts, using configuration qualifiers, that handle the size specific workflow.</li>
<li>Implement the pushing and popping of fragments using the techniques outlined above.</li>
</ul>


<p><em>Android is a trademark of Google Inc.</em></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Working in a Polyglot Environment]]></title>
    <link href="http://tech.infospace.com/2013/08/13/working-in-a-polyglot-environment/"/>
    <updated>2013-08-13T09:25:00+00:00</updated>
    <id>http://tech.infospace.com/2013/08/13/working-in-a-polyglot-environment</id>
    <content type="html"><![CDATA[<p><a href="http://www.merriam-webster.com/">Websters Dictionary</a> defines <a href="http://www.merriam-webster.com/dictionary/polyglot">Polyglot</a> as <strong><em>a mixture or confusion of languages or nomenclatures</em></strong>.  Mixture..confusion&hellip;. As computer scientists we&rsquo;re taught to not co-mingle or mix languages, platforms, metaphors and to write code that avoids confusion. When applying the term polyglot to computer science and taking the definition at face value it sounds just a tad bit negative or like something you want to avoid. It&rsquo;s hard enough to learn one language/platform well, right? Doesn&rsquo;t adding more languages into the mix just muddy the waters? In this post I want to give some practical reasons why a mixture of languages/platforms can help you be a better computer scientist and a more productive developer.</p>

<h3>You may already work in a polyglot environment and not even be aware of it.</h3>

<p>Are you a web developer? Do you write server side code hosted by Apache, Nginx, or IIS? Do you work on mobile applications? Do you make any 3rd party API calls?</p>

<p>If you answered yes to any of those questions you&rsquo;re most likely already working in a polyglot environment, at least from a language perspective. A typical web development environment, at a minimum, uses HTML, Javascript, and CSS. Calling an API? You&rsquo;re most likely using XML or JSON as well. Maybe you&rsquo;re using ASP.NET MVC or Ruby on Rails. All of those scenarios require a polyglot environment from a language perspective. Frameworks like ASP.NET and Rails provide mechanisms to blur the lines of the languages that are used and the frameworks that use them, but you&rsquo;re polyglot nonetheless.</p>

<h3>What can we learn from a polyglot environment?</h3>

<!--more-->


<p>So what does it matter if I&rsquo;m aware that I&rsquo;m working in a polyglot environment or not? You&rsquo;ll start to ask more thorough questions to the problems you&rsquo;re trying to solve as you gain more awareness of the environment you&rsquo;re working in. Being polyglot-aware frees you of the bondage of limiting your solutions to only the constructs available in your language. You start asking yourself questions like:</p>

<ul>
<li>Is my problem best solved using a pattern based around a language/framework construct, for example a Linq expression, or is there a design pattern that better solves my problem that may not already be implemented in the framework I&rsquo;m using.</li>
<li>Is my IDE or programming environment causing me to make workflow decisions that I would not make given a different IDE or programming environment?</li>
<li>How do other languages/platforms solve this problem? Are there best practices?</li>
</ul>


<h3>Polyglot environments allow us to learn from the growth of other platforms.</h3>

<p>If you&rsquo;ve paid attention to the evolution of .NET, Rails, Android, or iOS development over the last decade one thing you&rsquo;ll notice is that each framework/platform has <em>learned</em> from other frameworks/platforms. ORM&rsquo;s were introduced in the .NET Entity Framework as a direct result of their effectiveness in Rails. The understanding of the problems that ORM developers were trying to solve eventually lead to the NoSql boom that we&rsquo;re in today.</p>

<p>Android Studio and Interface builder for iOS have evolved, in part (in my opinion), as a result of the tools provided by Visual Studio for building forms/web forms based applications. Android fragments were heavily influenced by the boom in the the tablet market, driven by iOS. The pattern was different but the problem was surfaced and addressed as a direct result of another platform/framework. The UI evolution in iOS around notifications seems to be heavily influenced by their Android counterpart.</p>

<p>Polyglot environments have helped to proliferate language constructs like closures, lambdas, and generics. Even if you haven&rsquo;t been working in these different platforms/frameworks/languages a lot of the tools, patterns, and language constructs that you use everyday have been heavily influenced by people who do work in polyglot environments.</p>

<h3>Polyglot environments allow us to think outside the box</h3>

<p>In my experience, patterns tend to emerge quicker for the polyglot developer. I don&rsquo;t have any hard evidence for why but my gut tells me that it&rsquo;s because they&rsquo;re exposed to the patterns more often in different languages/frameworks and so they&rsquo;re more recognizable for what they really are (a pattern). Once you start recognizing patterns you can more easily differentiate the patterns from the language constructs that implement those patterns. When we&rsquo;re aware of the underlying pattern being implemented we are better able to utilize the construct implementing that pattern. It allows us to understand the bounding box of the construct and not try to shoehorn a solution into a construct that wasn&rsquo;t built to solve that problem.</p>

<p>As a polyglot developer you find yourself asking <em>&ldquo;Why am I solving the problem this way?&rdquo;</em> or <em>&ldquo;Is this really the best way to solve this problem?&rdquo;</em> more often. This leads to better solutions simply because you&rsquo;re more involved in <em><em>Why</em></em> you&rsquo;ve chosen a particular implementation. In my experience, polyglot developers are more likely to look for others who have solved the problem already than they are to just try to <em>roll their own</em> solution. Rolling your own solution to a commonly solved pattern often times causes us to miss some of the intricacies of the problem or introduce bugs that other frameworks have already squashed.</p>

<h3>I&rsquo;m convinced; how do I start?</h3>

<p>Find a problem that you&rsquo;re passionate about solving. Maybe you like reading RSS feeds, maybe you have a huge collection of books you&rsquo;d like to categorize, or maybe you&rsquo;re passionate about a problem with existing solutions that aren&rsquo;t up to snuff. Once you have a problem you&rsquo;re trying to solve pick a framework, language, and/or platform you&rsquo;ve never worked in like ASP.NET, Rails, Android, iOS, or etc and start solving your problem. You&rsquo;ll have a lot of fun because you&rsquo;ll be solving a problem you&rsquo;re passionate about and you&rsquo;ll be well on your way to becoming a polyglot developer.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Guard Your Java Code With AutoTest Tooling]]></title>
    <link href="http://tech.infospace.com/2013/08/01/guard-your-java-code-with-auto-testing/"/>
    <updated>2013-08-01T10:30:00+00:00</updated>
    <id>http://tech.infospace.com/2013/08/01/guard-your-java-code-with-auto-testing</id>
    <content type="html"><![CDATA[<p>I recently moved into doing Android development after spending a few years in Ruby and Node.js (after many, many years in .NET).
I have worked hard to shorten my personal code-health feedback loop to be as real-time as possible, so I can fix problems while retaining flow.
While many folks work on a set of changes and tests and run those tests every-so-often, I found it to be extremely helpful to get the feedback automatically every time I save changes to a file.</p>

<p>I have not found a suitable <strong>free</strong> solution for this type of thing for Java.
The solutions I have found typically require Eclipse or IntelliJ as well, and I&rsquo;ve been more productive sticking with Vim and Bash lately.
That being said, I wanted a solution that could support both IDE users and Text Editor users, just like I&rsquo;ve had in Ruby.</p>

<p>InfoSpace is happy to announce that we have released our <a href="https://github.com/infospace/guard-java">Guard::Java</a> project to the community, <strong>for free</strong> under an MIT-style license!</p>

<h2>Guard::Java</h2>

<p><a href="https://github.com/infospace/guard-java">Guard::Java</a> is built on top of my favorite auto-testing framework for Ruby, called <a href="https://github.com/guard/guard">Guard</a>, and provides automatic, background testing of your code <strong>as you are working, without you having to stop your workflow</strong>!
It provides this capability through the following features:</p>

<!--more-->


<ul>
<li>It watches your source and test files for changes</li>
<li>When a file changes, it tries to find the unit test fixture/class related to that file that changed</li>
<li>It runs <strong>just</strong> those tests, seeing if any basic unit tests for just that file have been violated or are now fixed</li>
<li>It can (optionally) after a successful single-class run, run <strong>all</strong> tests as a regression pass to see if any other unexpected impacts result from the changes you are making</li>
</ul>


<p>Guard also provides event and status notifications in various forms:</p>

<ul>
<li>Detailed output to the Console (e.g., in Eclipse or IntelliJ) or Shell</li>
<li>Terminal / Shell title bar text</li>
<li>Color coding of the session name when using TMUX</li>
</ul>


<div style="text-align: center"><img src="http://tech.infospace.com/images/guard_java_notifications/guard-java-tmux.png"></div>


<ul>
<li><a href="http://growl.info/">Growl</a> notifications (pop-up messages/toasts) with custom messages</li>
</ul>


<div style="text-align: center"><img src="http://tech.infospace.com/images/guard_java_notifications/guard-java-growl.png"></div>


<h2>How Does This Help Me?</h2>

<p>I just work the way I normally would, and my system tells me if I broke someting or if everything is still OK, without me lifting an extra finger!
While Guard::Java comes with sensible defaults for most common scenarios, it can also be configured for your specific situation.</p>

<h2>What About Android Tests?</h2>

<p>Yes, running Android tests are a pain since they are deployed to a device/emulator and fully run.  In this case, we have adopted the following workflow:</p>

<ul>
<li>Guard::Java watches file changes and automatically compiles the code and/or tests on every save action to ensure nothing has broken</li>
<li>It has a prompt in your Console/Shell that you can simply hit ENTER on and it will build, deploy, and run your tests using the standard ant tasks (or your own customized tasks) and report status all along the way.</li>
</ul>


<p>The Guardfile that is generated when you run <em>guard init</em> already has code to automatically find your Android SDK folder and add it to the classpath as well!</p>

<h2>I Use Eclipse/IntelliJ &ndash; Do I Need This?</h2>

<p>It depends.  If you have it configured to autotest specific code with each save, then you may not need or want this.
The nice thing is that we have used this in Eclipse and IntelliJ (configuring as an External Tool, for example) using a Console tab in the IDE.
We also have used this with folks using Text Editors (Sublime Text, ViM, and TextMate) with success.</p>

<h2>It Doesn&rsquo;t Do What I Need</h2>

<p>We are happy to take suggestions and pull requests.  Just open an issue&mdash;or better yet a Pull Request&mdash;from the repository at <a href="https://github.com/infospace/guard-java">https://github.com/infospace/guard-java</a></p>

<h2>How Do I Get Started</h2>

<p>See the README on the <a href="https://github.com/infospace/guard-java">project page on GitHub</a> to get started!</p>

<p>Suggestions, feedback, and ideas are always welcome!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Storing User Passwords using Salt + Hashing]]></title>
    <link href="http://tech.infospace.com/2013/07/22/storing-user-passwords-using-salt-plus-hashing/"/>
    <updated>2013-07-22T19:30:00+00:00</updated>
    <id>http://tech.infospace.com/2013/07/22/storing-user-passwords-using-salt-plus-hashing</id>
    <content type="html"><![CDATA[<p>Many developers store passwords wrong.  Are you one of them?  Likely, you&rsquo;ve stored them in a vulnerable way in the past and maybe you still are.  If your company doesn&rsquo;t have a standard pattern for storing user passwords, or if it does and the pattern doesn&rsquo;t contain the words &ldquo;Salt&rdquo; and &ldquo;Hash&rdquo;, this blog post is for you.</p>

<p>When writing user passwords to a datastore, never store them in plain text.  If your datastore&rsquo;s security is compromised, an attacker can easily steal user login credentials, unleashing a major PR incident on your watch.  Don&rsquo;t worry, it isn&rsquo;t much effort to plan ahead and only incur a minor PR incident, none of which is your fault.</p>

<h2>Is there a better way to store passwords than plain text?</h2>

<p>Yes!  Instead of storing the actual password text, store a hash of that password.  Use a strong hashing algorithm like SHA256 or SHA512 to hash the password text and store the result of that.  When a user needs to be authenticated, hash the submitted password and compare the two hashes.  If they are the same, the password is correct.  Unfortunately, hashing alone is not all that much more secure due to something called a rainbow table.  Rainbow tables are very large sets of hashed passwords that can be used to convert hashes back to plain text passwords.  These tables are readily available through BitTorrent.</p>

<h2>Is there a better way to store passwords than using hashes?</h2>

<p>Yes!  Instead of storing the hash of the password, store a hash of a salted password.  A salt is a random string (and unique to each password in your system) that you will append to the password before hashing it.  And get this, you&rsquo;ll store that salt in your datastore in plain text in the column right next to the hash!</p>

<h2>What?  Are you out of your mind?!</h2>

<p> <!--more-->
No!  It turns out that even if the attacker has the salt and the hash, it doesn&rsquo;t do them any good.  Remember that storing plain hashes isn&rsquo;t good because of precomputed rainbow tables.  These tables are computed off of a large set of text passwords, not passwords with salts on them.  The attacker would have to regenerate the tables using the salt from your database and since the salt is unique to each password, generating a different table for each password would take too much time to be a viable option.  So using long unique salts is important.  Something in the neighborhood of 128 chars should do it.  The salts should be random and you should use a Cryptographically Secure Pseudo-Random Number Generator (CSPRNG) to generate them.</p>

<h2>Why can&rsquo;t I write my own hash algorithm?</h2>

<p>So the attacker doesn&rsquo;t know what it is and they can&rsquo;t create a rainbow table for it, right? This is called security through obscurity and it is a very bad idea.  Unless you&rsquo;re a cryptographer and can prove that your algorithm is a secure cryptographic hash function, don&rsquo;t go this route.  Once the hashing function is reverse engineered, plain text passwords can be computed from the hashes.  A rainbow table isn&rsquo;t even required if the passwords fall out of the hashes if you shake them a little bit.</p>

<h2>I forgot my password on site X and they sent it to me in an email.  How does that work?</h2>

<p>Well, they are storing your password in their system and it is vulnerable.  Not to mention that they sent your password over the wire in an email that isn&rsquo;t necessarily encrypted.  Stop using that site and delete your account.  Then email the site admin and have them read this blog.  A coworker of mine ran into this very thing a couple weeks ago on a major home services provider site.  This is still a real problem so spread the word and educate your fellow developers.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Route53 DNS Failover Webinar]]></title>
    <link href="http://tech.infospace.com/2013/07/09/route53-dns-failover-webinar/"/>
    <updated>2013-07-09T11:36:00+00:00</updated>
    <id>http://tech.infospace.com/2013/07/09/route53-dns-failover-webinar</id>
    <content type="html"><![CDATA[<p>This morning, Amazon Web Services hosted a webinar on using Route 53 DNS failover to provide high-availability solutions. Sean Meckley, Product Manager for Route 53, shared how this feature allows you to build applications that are resilient to failures. We were invited to share how InfoSpace uses Route 53 to enable automatic failover between AWS regions. I shared some details on our multi-region architecture, how we setup latency based routing with health checks, how we tested the service to make sure it worked for our use cases, and our results (we get automatic failover between AWS regions in about 150 seconds).</p>

<p>You can get the slides <a href="http://www.slideshare.net/AmazonWebServices/webinar-route53-dnsfailoverfinal">here</a> and watch the presentation <a href="http://www.youtube.com/watch?v=3OK6VG7gqiw&amp;list=PLhr1KZpdzukeUoelFoS68SRfY6pA_Ib6A&amp;index=23">here</a> (we talk about InfoSpace starting around the 25:00 mark).</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[To the Cloud!]]></title>
    <link href="http://tech.infospace.com/2013/07/01/to-the-cloud/"/>
    <updated>2013-07-01T09:00:00+00:00</updated>
    <id>http://tech.infospace.com/2013/07/01/to-the-cloud</id>
    <content type="html"><![CDATA[<p>We&rsquo;ve just finished moving all of InfoSpace&rsquo;s search traffic to the cloud. It&rsquo;s been a monumental effort and we&rsquo;ve learned a lot along the way. As of today, 100% of our search traffic is served up via Amazon Web Services (AWS).</p>

<p>Our journey began a little less than a year ago. We spent the first few months prototyping our architecture in AWS. During these months, we used this time to prove that our services could run in the cloud, evaluated cloud providers, and did some initial performance testing.</p>

<p>The real work started in earnest just after the start of 2013. In the past five months, we&rsquo;ve organically developed a skilled team of engineers who are now well versed in all-things AWS: from VPCs, ELBs and ASGs to load-balanced DNS, Asgard and cloud security, we&rsquo;ve built up a lot of skills and experience in a very short time.</p>

<p>Simultaneously with our move to AWS, we have had a project to consolidate our two datacenters down to one smaller presence. There&rsquo;s a ton of logistical difficulties, contractural commitments and resource challenges we worked out &ndash; managing the timing and numerous dependencies was critical to the success of this project.</p>

<p>We&rsquo;re going to cover several topics over the next few months about our plan to move out of the datacenters to the cloud, specific technologies and architecture choices we made, as well as how things are running as we gain more operational experience with it. Come back and visit our blog often as we chronicle our journey.</p>

<h2>Upcoming topics</h2>

<ul>
<li>Application architecture for multi-region deployments</li>
<li>Global load-balancing using Route 53</li>
<li>Fire and Forget: A performance testing approach</li>
<li>Our Cloud-Ops approach</li>
<li>Our resilient, redundant AWS architecture</li>
<li>Lessons learned, landmines to avoid</li>
</ul>


<p>Meanwhile, our Director of IT/Operations, Wayson, will start a series discussing our datacenter consolidation project.</p>

<p>We&rsquo;re looking forward to sharing our experiences with you. And, if you&rsquo;re looking for a great place to work with cloud technologies, <a href="http://ch.tbe.taleo.net/CH02/ats/careers/searchResults.jsp?org=INFOSPACE&amp;cws=1">InfoSpace is hiring</a>!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[What it's like to work at InfoSpace: My first two months]]></title>
    <link href="http://tech.infospace.com/2013/05/30/what-its-like-to-work-at-infospace-my-first-two-months/"/>
    <updated>2013-05-30T19:10:00+00:00</updated>
    <id>http://tech.infospace.com/2013/05/30/what-its-like-to-work-at-infospace-my-first-two-months</id>
    <content type="html"><![CDATA[<p>Back in the beginning of April, I joined the ranks of InfoSpace.  As you would expect, I was filled with the typical excitement and anticipation of someone who is about to start working for a new company.  What will I be working on?  What will the team be like?  What’s the culture like?  And of course, how fast will my work machine be?</p>

<p>Having been around the block in this industry, I have to say I was really surprised when I began working at InfoSpace.  It <em>really is</em> unique!</p>

<p>Let me explain by giving you a peek inside at my experience over the last two months.  If you’re someone who believes software engineering is as much engineering as it is art, then you’ll be right at home here.  InfoSpace places a great deal of emphasis on the craftsmanship of writing code.  So much so, they have several book clubs that read and then meet to discuss chapters from the book <a href='http://www.amazon.com/Clean-Code-Handbook-Craftsmanship-ebook/dp/B001GSTOAM/'>Clean Code</a>, by Robert C. Martin.  At the meetings, the groups get together to discuss what they’ve read.  They debate the relevance of the points in the chapter, or share experiences about how what they read helped them improve their craft.  Along these lines, InfoSpace provides a clearly stated definition of what is means to be ‘done’ with a given task.  Included in that definition are incorporating unit tests for the code check-in and having a code review.  Reviewers take time to offer suggestions of ways to make the code more elegant or more efficient.  To put it another way, the focus is not just on getting it done, but getting it done right, even if that means it takes a little bit longer.  Ultimately, everyone at InfoSpace improves as an engineer.
 <!--more--></p>

<p> As part of that improvement process, they have bi-weekly ‘Lightning Talks’.  Everyone gets together for some quick presentations on a bit of technology, engineering, or new idea that is trending in the software development industry.  The talks let us share with one another something we just learned, or just think is cool.  They’re  a great way, and a fun way, for everyone to share their knowledge, expand their horizons, and speak geek with their coworkers.</p>

<p>The culture at InfoSpace is lighthearted.  Folks here are social and friendly.  Since I’ve joined, I’ve had several people introduce themselves to me and ask me how I’m doing.  And many times during those conversations, they’ve mentioned how much InfoSpace encourages a work/life balance.  While everyone enjoys working hard on their projects, InfoSpace recognizes their employees have lives outside the office.  We all know it’s a competitive world, but pressuring employees to work nights and weekends only grinds them down.  InfoSpace focuses on a healthy balance, acknowledging that folks need a chance to recharge their batteries.  In addition to everything else they do, there are social gatherings, sometimes on Friday afternoons, to help keep things light.  And InfoSpace has chosen to support a softball team this summer.  It’s a testament to their commitment to work/life balance that I really have no idea how many hours I work each week.  I think that says a lot.</p>

<p>All in all, joining InfoSpace is one of the best decisions I’ve made for my career, and my happiness, in a long time.  When was the last time you couldn’t wait to get to work?  For me now, it’s every morning.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Side Projects and the Intrapreneurial Spirit]]></title>
    <link href="http://tech.infospace.com/2013/05/30/side-projects-and-the-intraprenerurial-spirit/"/>
    <updated>2013-05-30T14:17:00+00:00</updated>
    <id>http://tech.infospace.com/2013/05/30/side-projects-and-the-intraprenerurial-spirit</id>
    <content type="html"><![CDATA[<p>Every engineer should have a project on the side.  An initiative focused on improving the business, controlled completely by the engineer.  My side projects get me up in the morning and get me excited about coming to work.  That&rsquo;s not to say I don&rsquo;t enjoy my normal work activities, but my side projects are green field, controlled 100% by me and are exciting.</p>

<p>These types of projects are the reason you got into computer science in the first place.  Who comes up with the feature requirements?  You do.  Who defines the development process?  You do.  Who gets the glory when the project is the next big thing?  You get the idea.</p>

<p>Engineer driven projects are becoming increasingly important to keep businesses relevant and evolving.  They keep products fresh, technology fresher, and can help make a lot of money.  You should be a leader in your company to push this movement forward.  You should be an intrapreneur.</p>

<h2>Where do I get ideas for projects?</h2>

<p>The first criteria for picking a side project is that you are excited about it.  No one is asking you to get this work done so if you&rsquo;re not exciting about blazing the trail with your ideas and passion, the project isn&rsquo;t going to go anywhere.  You should feel a deep sense of ownership that its fate is in your hands.  No one is going check up on it and see how it is going.  Own it.  Get it done.
 <!--more-->
Next, start listening.  Everybody&rsquo;s got problems.  Listen closely to the problems that are opportunities for improvement.  &ldquo;I wish I had a tool that&hellip;&rdquo;, &ldquo;Our API is clunky, I wish&hellip;&rdquo;, &ldquo;There gotta be a better way to do&hellip;&rdquo;, there is no shortage of needs if you are listening for them.  Keep a catalog of potential ideas and keep listening even when your bandwidth is maxed out and save them for later.  Now that you have a list, you just need to pick one.  Pick the one that you are both excited about and has the largest potential impact.  Imagine the smiles on the faces of the people when they are pleasantly surprised that you secretly fixed their problem in your spare time.</p>

<h2>What is Success?</h2>

<p>It depends on what you&rsquo;re trying to accomplish.  Some projects are internal to your team and success is other team members approving your code branch to be merged in.  Some are small independent tools that are developed end to end and given directly to the end user.  If they use it and it is helpful, success!</p>

<p>My favorite type of project is the new product feature proof of concept.  Success means proving that the concept of a large scale change works or it doesn&rsquo;t.  The end result needs to be testable and verifiable to be valuable.  Product developers are always looking for fresh ideas that they can confidently invest in.  If you prove your own ideas should be invested in, you&rsquo;ll get the resources to do so.  And you&rsquo;ll likely be the visionary that will get to lead it to even more success.</p>

<h2>The Best Part</h2>

<p>The best part is that it&rsquo;s all risk free.  If you try something new and crazy and it flops, who cares.  All you&rsquo;re out is the spare time it took to build it.  Now, don&rsquo;t get me wrong, time is very valuable and I don&rsquo;t recommend failing.  Time working on a failing idea could be spent on a successful one, but if you do fail, learn something and move on to the next project.</p>

<p>The second best part is that you work for a company that (likely) has resources.  You have access to people, software and hardware (you might need to get permission first) that can help you succeed.  As long as you can fit it into your spare time and your ask isn&rsquo;t too taxing.</p>

<h2>Ok, But&hellip;</h2>

<p>It sounds like I&rsquo;m going to be doing a bunch of optional hard work.  Why should I work so hard for a company that doesn&rsquo;t care about me?  Well, you shouldn&rsquo;t.  If you truly believe your company doesn&rsquo;t care if you innovate or not and you don&rsquo;t see other innovators being rewarded for their achievements, do yourself a favor and find a company that does.  Many companies know the value of intrapreneur innovation and you should find one of those.  Oh, and <a href="http://ch.tbe.taleo.net/CH02/ats/careers/searchResults.jsp?org=INFOSPACE&amp;cws=1">InfoSpace is hiring</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Android Build Automation]]></title>
    <link href="http://tech.infospace.com/2013/05/29/android-build-automation/"/>
    <updated>2013-05-29T16:37:00+00:00</updated>
    <id>http://tech.infospace.com/2013/05/29/android-build-automation</id>
    <content type="html"><![CDATA[<p>I&rsquo;m a big fan of <a href="http://martinfowler.com/bliki/ContinuousDelivery.html">Continuous Integration/Continuous Delivery</a>.  Continuous Integration gives us more confidence in our code by helping us to identify bugs earlier in the development lifecycle. With <a href="http://softwaremaintenanceengineer.blogspot.com/2009/09/im-developer-there-is-no-money-in.html">Software Maintenance</a> representing up to 90% of the total cost of ownership for software, the sooner a bug is found in the process the less frustration, time, and energy that will be needed to fix the bug. This can have any number of downstream effects including purposefully or inadvertently creating code that works around or becomes dependent upon the bug.</p>

<p>Continuous Integration also encourages us to <a href="http://www.codinghorror.com/blog/2008/08/check-in-early-check-in-often.html">check in early and check in often</a>.  Checking in early and often helps us decrease the surface area of our change, thus decreasing the amount of code that can introduce bugs in the system. <a href="http://www.codinghorror.com/blog/2008/08/check-in-early-check-in-often.html">Checking in early and check in often</a> becomes even more effective when it&rsquo;s coupled with unit/behavior tests.  Having unit/behavior tests allow us to ensure consistency in functionality and behavior across changes.  It gives us the confidence that our change, no matter how small, hasn&rsquo;t changed the behavior of the system. It also allows us to ensure that previous bug fixes and features continue to work as designed. Most importantly, having tests allows you to identify areas of the code that can be cleaned up, refactored, or just don&rsquo;t behave as expected.</p>

<p>So you may be asking yourself what all this has to do with automating builds for Android<sup>TM</sup> applications. Strictly speaking automating Android application builds consists of:</p>

<!--more-->


<ul>
<li>Having a machine setup with the latest version of your software (and optionally signing certificate for release builds)</li>
<li>Triggering a build given some set of conditions</li>
<li>Archiving the build somewhere.</li>
</ul>


<p>Here&rsquo;s where the introductory paragraphs become important.  I would argue that having a <em>reliable</em> automated Android application build consists of the following in addition to the minimum requirements above:</p>

<ul>
<li>Having your source version controlled</li>
<li>Having unit/behavior/integration tests that verify the functionality of your software</li>
<li>Being able to trigger an Android application build from source control commits and have that build run the tests each time.</li>
</ul>


<p>That&rsquo;s exactly the system we&rsquo;ve built here at <a href="http://www.infospace.com">InfoSpace</a> to automate our Android application builds.  Here&rsquo;s a high level walk through of our automated build process.</p>

<h1>The Tech</h1>

<p><img src="http://tech.infospace.com/images/android_automated_builds/the_tech.png"></p>

<h1>The Workflow</h1>

<blockquote><p>Our workflow varies per Android project depending on the build task (building and testing our libraries, building our release APK&rsquo;s, or etc).</p></blockquote>

<p>Our process</p>

<p><img src="http://tech.infospace.com/images/android_automated_builds/the_process.png"></p>

<h1>The Gotchas</h1>

<p>The first gotcha is that the built-in Android application build <em>test</em> ant task ALWAYS returns a success exit code for its process regardless of whether or not the tests fail. This means that we can&rsquo;t fail the build during the test portion of the build process if the project compiles but fails the tests.</p>

<p>The second gotcha is that you can&rsquo;t run any of the ant tasks in the post build process. If we could do that then we&rsquo;d have a way to work around the first gotcha by running the &ldquo;Text Finder&rdquo; plugin, which will fail the build, before running the ant task to build the release bits.</p>

<p>So what we&rsquo;re stuck with right now is a scenario which isn&rsquo;t ideal but is functional. If someone checks in code that compiles but doesn&rsquo;t work functionally (i.e. the tests fail) it will still drop the release bits to our Dropbox archive.  But we&rsquo;ll get notified that the build failed and know not to use those release bits.  Dropbox allows for file history so we can get the last known good build from Dropbox.  But in the even that we can&rsquo;t get it on Dropbox we take advantage of the ability to archive the build bits via the Jenkins project directly on the build server. If we needed to we could always go back and get the last known good build directly from Jenkins.</p>

<h1>What&rsquo;s next</h1>

<p>We&rsquo;re going to take a look at the new <a href="http://developer.android.com/sdk/installing/studio.html#download">Android Studio</a> and see if this can aid in overcoming the gotchas in our build process.</p>
]]></content>
  </entry>
  
</feed>
