<?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>California Dreams</title>
	<atom:link href="http://www.heikkitoivonen.net/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.heikkitoivonen.net/blog</link>
	<description>A Finn in Silicon Valley - Adventures in Technology</description>
	<lastBuildDate>Wed, 09 Feb 2011 05:57:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.5</generator>
		<item>
		<title>Beware of cPickle</title>
		<link>http://www.heikkitoivonen.net/blog/2011/02/08/beware-of-cpickle/</link>
		<comments>http://www.heikkitoivonen.net/blog/2011/02/08/beware-of-cpickle/#comments</comments>
		<pubDate>Wed, 09 Feb 2011 04:59:34 +0000</pubDate>
		<dc:creator>Heikki Toivonen</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.heikkitoivonen.net/blog/?p=1163</guid>
		<description><![CDATA[The Python pickle module provides a way to serialize and deserialize Python objects. A large downside of the pickle format is that it is not secure, meaning you should not deserialize pickles received from untrusted sources. There is also a cPickle version of the pickle module which implements the algorithm in C and is much [...]]]></description>
			<content:encoded><![CDATA[<p>The Python <a href="http://docs.python.org/library/pickle.html">pickle</a> module provides a way to serialize and deserialize Python objects.  A large downside of the pickle format is that it is not secure, meaning you should not deserialize pickles received from untrusted sources. </p>
<p>There is also a <code>cPickle</code> version of the pickle module which implements the algorithm in C and is much faster than the pure Python module. This provides somewhat surprising use cases for the <code>cPickle</code> module besides the obvious application save format: it turns out <code>cPickle</code> can be the <a href="http://stackoverflow.com/questions/1410615/copy-deepcopy-vs-pickle">fastest way to make a copy</a> of nested structures. Due to speed, using <code>cPickle</code> can also be attractive as a data format between trusted servers.</p>
<p>There is an issue that you need to watch out for in the <code>cPickle</code> module, though. When you are serializing to or deserializing from string using the <code>dumps</code> and <code>loads</code> functions respectively, the functions do not release the <a href="http://wiki.python.org/moin/GlobalInterpreterLock">GIL</a>! This took me by surprise: I did not expect anything in the stdlib to hold on to the GIL for anything that could potentially take a long time. You can try this out easily by creating a multithreaded application where one thread tries to use <code>cPickle.dumps</code> on multimegabyte data structure while the other treads are printing to screen for example. You will see that while <code>dumps</code> is running, the other threads are stopped.</p>
<p>Luckily there is an easy workaround: you can use the <a href="http://docs.python.org/library/pickle.html#pickle.load"><code>load</code></a> and <a href="http://docs.python.org/library/pickle.html#pickle.dump"><code>dump</code></a> functions with <a href="http://docs.python.org/library/stringio.html#module-cStringIO">cStringIO</a> buffer or other file-like objects.</p>
<p>Note that I haven&#8217;t checked if this problem applies to Python 3.x.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.heikkitoivonen.net/blog/2011/02/08/beware-of-cpickle/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Decorator to Log Slow Calls</title>
		<link>http://www.heikkitoivonen.net/blog/2011/02/02/decorator-to-log-slow-calls/</link>
		<comments>http://www.heikkitoivonen.net/blog/2011/02/02/decorator-to-log-slow-calls/#comments</comments>
		<pubDate>Thu, 03 Feb 2011 06:33:07 +0000</pubDate>
		<dc:creator>Heikki Toivonen</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.heikkitoivonen.net/blog/?p=1153</guid>
		<description><![CDATA[One of the most common examples given for Python decorators is a decorator that tracks how long the execution of the wrapped function took. While this is very useful in and of itself, it can cause issues when you want to apply that into production usage. The issue I faced was that when I was [...]]]></description>
			<content:encoded><![CDATA[<p>One of the most common examples given for Python decorators is a decorator that tracks how long the execution of the wrapped function took. While this is very useful in and of itself, it can cause issues when you want to apply that into production usage.</p>
<p>The issue I faced was that when I was trying to find out why my servers were too slow (only under production loads), I first added the simple timing decorators to everything I thought might be slow in the hopes of catching all the slow calls and maybe finding some patterns. Well, this approach worked in the sense that I did find the slow parts quickly, but it was producing much more logs than before, and I wasn&#8217;t really interested in most of this timing information.</p>
<p>What I really wanted was a timing decorator that would log only when the wrapped callable took too long to execute. But there were still some calls that I wanted to log always for accurate statistical purposes. I figured the best way was to make my decorator take a threshold argument with some reasonable default that I could override if I wanted.</p>
<p>Now while I have written decorators before, this was the first decorator that called for optional arguments. Python treats decorators that don&#8217;t take any arguments slightly differently from those that require arguments, so this complicates things a bit. The sample in <a href="http://wiki.python.org/moin/PythonDecoratorLibrary#Creatingdecoratorwithoptionalarguments">Python decorator library</a> is almost scary! I think my approach is nice and simple yet fairly sophisticated:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">time</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">logging</span>
<span style="color: #ff7700;font-weight:bold;">import</span> functools
&nbsp;
log = <span style="color: #dc143c;">logging</span>.<span style="color: black;">getLogger</span><span style="color: black;">&#40;</span>__name__<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> time_slow<span style="color: black;">&#40;</span>f=<span style="color: #008000;">None</span>, logger=log, threshold=<span style="color: #ff4500;">0.01</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> decorated<span style="color: black;">&#40;</span>f<span style="color: black;">&#41;</span>:
        @functools.<span style="color: black;">wraps</span><span style="color: black;">&#40;</span>f<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">def</span> wrapper<span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kw<span style="color: black;">&#41;</span>:
            start = <span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">try</span>:
                ret = f<span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kw<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">finally</span>:
                duration = <span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> - start
                <span style="color: #ff7700;font-weight:bold;">if</span> duration <span style="color: #66cc66;">&gt;</span> threshold:
                    logger.<span style="color: black;">info</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'slow: %s %.9f seconds'</span>, f.__name__, duration<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">return</span> ret
        <span style="color: #ff7700;font-weight:bold;">return</span> wrapper
    <span style="color: #ff7700;font-weight:bold;">if</span> f <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">None</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> decorated<span style="color: black;">&#40;</span>f<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> decorated</pre></div></div>

<p>This decorator can be placed on a callable without any arguments, or with a custom logger or threshold value. In other words, both of these would work:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">@time_slow
<span style="color: #ff7700;font-weight:bold;">def</span> myfast<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">pass</span>
&nbsp;
@time_slow<span style="color: black;">&#40;</span>threshold=<span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">def</span> myslow<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">time</span> <span style="color: #ff7700;font-weight:bold;">import</span> sleep
    sleep<span style="color: black;">&#40;</span><span style="color: #ff4500;">0.001</span><span style="color: black;">&#41;</span></pre></div></div>

<p>and typically calling <code>myslow</code> only would produce log output. I chose 0.01 as a reasonable default threshold, but this of course depends a lot on the use case. The log includes the slow function&#8217;s name, as well as the time formatted with 9 decimals in order to avoid the exponential notation, which makes it easier to work with the log output (<a href="http://linux.die.net/man/1/sort"><code>sort -n</code></a>, for example). I have just used a single threshold, but an easy improvement would be to pass a list of thresholds and log at different <a href="http://docs.python.org/library/logging.html#logging-levels">levels</a> depending on the duration.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.heikkitoivonen.net/blog/2011/02/02/decorator-to-log-slow-calls/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>M2Crypto Supports OpenSSL 1.0.x</title>
		<link>http://www.heikkitoivonen.net/blog/2011/01/16/m2crypto-supports-openssl-1-0-x/</link>
		<comments>http://www.heikkitoivonen.net/blog/2011/01/16/m2crypto-supports-openssl-1-0-x/#comments</comments>
		<pubDate>Mon, 17 Jan 2011 05:32:40 +0000</pubDate>
		<dc:creator>Heikki Toivonen</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[m2crypto]]></category>

		<guid isPermaLink="false">http://www.heikkitoivonen.net/blog/?p=1149</guid>
		<description><![CDATA[I was supposed to release new M2Crypto version in the summer of 2010 but &#8220;real life&#8221; got in the way, and this extended all the way until this week. I finally decided that I&#8217;d better push out a new release even though there was just one significant change: OpenSSL 1.0.x support. However, I felt this [...]]]></description>
			<content:encoded><![CDATA[<p>I was supposed to release new <a href="http://chandlerproject.org/Projects/MeTooCrypto">M2Crypto</a> version in the summer of 2010 but &#8220;real life&#8221; got in the way, and this extended all the way until this week. I finally decided that I&#8217;d better push out a new release even though there was just one significant change: <a href="http://www.openssl.org/">OpenSSL</a> 1.0.x support. However, I felt this was really important since OpenSSL 1.0.x has been out for almost a year now, and it is starting to get difficult to deal with software that does not work with pre-1.0.x.</p>
<p>Unfortunately I made a mistake in my first release to <a href="http://pypi.python.org/pypi/M2Crypto">PyPI</a>: I used the <code>setup.py</code> commands to build, sign and upload a source distribution, but I did this from a tree I had <code>svn export</code>ed. Due to the way the M2Crypto <code>setup.py</code> was constructed this meant that the tarball was lacking vital files. Yesterday I did a new 0.21.1 release from the Subversion checkout, so the tarball now includes everything.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.heikkitoivonen.net/blog/2011/01/16/m2crypto-supports-openssl-1-0-x/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Long Silence</title>
		<link>http://www.heikkitoivonen.net/blog/2011/01/10/long-silence/</link>
		<comments>http://www.heikkitoivonen.net/blog/2011/01/10/long-silence/#comments</comments>
		<pubDate>Tue, 11 Jan 2011 05:50:46 +0000</pubDate>
		<dc:creator>Heikki Toivonen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.heikkitoivonen.net/blog/?p=1137</guid>
		<description><![CDATA[If you have been following my blog you have probably noticed I haven&#8217;t been writing, or in fact doing anything publicly in the last few months. A lot happened in my personal life, for example I moved to Santa Clara, but more importantly I was buried with work. It is weird how I always read [...]]]></description>
			<content:encoded><![CDATA[<p>If you have been following my blog you have probably noticed I haven&#8217;t been writing, or in fact doing anything publicly in the last few months. A lot happened in my personal life, for example I moved to Santa Clara, but more importantly I was buried with work.</p>
<p>It is weird how I always read about other people working insane hours at startups, but it hadn&#8217;t really happened to me. Sure, especially early on in my career I did put in a few all nighters, but not consistently. This time it was different.</p>
<p>I had been working on a large project for several months, of which I was the main architect and developer, and we finally deployed it into production. And all hell broke loose! Some problems could have been avoided by having had a better test setup (especially load testing), some was my inexperience dealing with heavily loaded system, some we could caulk to 3rd party software not quite ready for prime time, some to running software on VMs when we should have run on bare hardware, some to bizarre VM freezes (like minutes at time, which is obviously disastrous for a server), some lessons learned with Python GIL and multithreaded applications, plus various other bits and pieces and finally made worse by our steady and respectable growth in both number customers and sizes of data sets. I plan to write about some of that in later posts.</p>
<p>Since customers were being affected, and we didn&#8217;t see the full scope of problems in advance, I thought I would work extra hours and fix the issues. I was being optimistic, and assumed just the most pressing issue that was killing us was the one that would get us over the hump. This turned into days, then weeks, then months of working 60-70 hour weeks, 6-7 days a week on 5-6 hours of sleep, fixing issue after issue after issue. Combine this with the move to a new city and things were really crazy for a while. I don&#8217;t understand how I did it, given how little time we had to test on many occasions, but I believe I never introduced a catastrophic bug that got rolled into production (if you discount the initial deployment <img src='http://www.heikkitoivonen.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . Finally, just before Christmas, things started humming the way I had planned and how they had worked in our tests months before. Of course there is still a lot of work to do to improve things, but they can be addressed in a more sustainable pace.</p>
<p>Luckily the work I was doing was very interesting, or I wouldn&#8217;t have been able to do it for such a long period. In retrospect I can now finally say that I have now personally faced the problem of scaling, and while I&#8217;ve always said it is a good problem to have, I now also realize trying to solve it can easily lead to exhaustion because the pressure is huge to solve the issues quickly.</p>
<p>While I learned a lot of things and will be able to avoid some of the issues in the future, this also clearly showed what kind of testing we still need to do better. Besides being better for users of the software, it is also better for developer health and sanity&#8230;</p>
<p>I am still recovering from that ordeal both mentally and physically, but I have been feeling much better. I do realize I am suffering from some burnout, but I am also starting to get the itch to continue developing my own software, both free and paid. M2Crypto release has been pending for around 6 months now, and my Android apps are really in need of an upgrade.</p>
<p>I am also months behind in some personal correspondence. So sorry! I will try to get my inbox in order in the next couple of weeks as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.heikkitoivonen.net/blog/2011/01/10/long-silence/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>EV Guidelines Holding Up</title>
		<link>http://www.heikkitoivonen.net/blog/2010/09/14/ev-guidelines-holding-up/</link>
		<comments>http://www.heikkitoivonen.net/blog/2010/09/14/ev-guidelines-holding-up/#comments</comments>
		<pubDate>Wed, 15 Sep 2010 05:09:36 +0000</pubDate>
		<dc:creator>Heikki Toivonen</dc:creator>
				<category><![CDATA[Security]]></category>
		<category><![CDATA[ssl]]></category>

		<guid isPermaLink="false">http://www.heikkitoivonen.net/blog/?p=1133</guid>
		<description><![CDATA[About a month ago I was reading a post how one can use a browser while disabling all certificates that it ships with. While this can work, it is definitely not for the lazy or someone not very familiar with the issues. The author&#8217;s comment that it was trivial to get an EV certificate with [...]]]></description>
			<content:encoded><![CDATA[<p>About a month ago I was reading a post how one can <a href="https://blog.torproject.org/blog/life-without-ca">use a browser while disabling all certificates that it ships with</a>. While this can work, it is definitely not for the lazy or someone not very familiar with the issues. The author&#8217;s comment that it was trivial to get an <a href="http://en.wikipedia.org/wiki/Extended_Validation_Certificate">EV certificate</a> with nothing but email verification got me worried, since this should not have been possible per the EV <a href="http://www.cabforum.org/Guidelines_v1_2.pdf">guidelines</a> (PDF).</p>
<p>I tried to comment, but comments had already been closed. I tried to find the author&#8217;s email address, but could not (in a couple of minutes of searching that I had available), so I filed a bug to Mozilla to track this down. Luckily it turns out the comment is misleading, and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=587355#c3">EV guidelines were followed</a>. Thanks to Kathleen Wilson for tracking down the post author and clarifying things!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.heikkitoivonen.net/blog/2010/09/14/ev-guidelines-holding-up/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SSL in Python 2.7</title>
		<link>http://www.heikkitoivonen.net/blog/2010/08/23/ssl-in-python-2-7/</link>
		<comments>http://www.heikkitoivonen.net/blog/2010/08/23/ssl-in-python-2-7/#comments</comments>
		<pubDate>Tue, 24 Aug 2010 04:20:24 +0000</pubDate>
		<dc:creator>Heikki Toivonen</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[m2crypto]]></category>

		<guid isPermaLink="false">http://www.heikkitoivonen.net/blog/?p=1109</guid>
		<description><![CDATA[It has been almost two years since I wrote about the state of SSL in Python 2.6. If you haven&#8217;t read that yet, I suggest you read that first and then continue here, since I will mostly just be talking about things that have changed since then, or things that I have discovered since then. [...]]]></description>
			<content:encoded><![CDATA[<p>It has been almost two years since I wrote about the state of <a href="http://www.heikkitoivonen.net/blog/2008/10/14/ssl-in-python-26/">SSL in Python 2.6</a>. If you haven&#8217;t read that yet, I suggest you read that first and then continue here, since I will mostly just be talking about things that have changed since then, or things that I have discovered since then.</p>
<p>The good news is that things have improved in the stdlib <a href="http://docs.python.org/library/ssl.html">ssl</a> module. The bad news is that it is still missing some critical pieces to make SSL secure. </p>
<p>Python 2.7 enables you to specify ciphers to use explicitly, rather than just relying on what comes default with the SSL version selection. Additionally, if you compile the <code>ssl</code> module with OpenSSL 1.0 and later, using <code>ssl.PROTOCOL_SSLv23</code> is safe (as in, it will not pick the insecure SSLv2 protocol) as long as you don&#8217;t enable SSLv2 specific ciphers (see the ssl module documentation for details).</p>
<h3>Servers</h3>
<p>With that out of the way, there isn&#8217;t really much difference to how you would write a simple SSL server with Python 2.7 compared to what I wrote in 2008. If you know your <code>ssl</code> module was compiled with OpenSSL 1.0 you can pick <code>ssl.PROTOCOL_SSLv23</code> for maximum compatibility. Otherwise you should stick with an explicit version other than v2.</p>
<p>The documentation for the ssl module in 2.7 has improved a lot, and includes good sample code for servers <a href="http://docs.python.org/library/ssl.html#server-side-operation">here</a>.</p>
<p>The <a href="http://chandlerproject.org/Projects/MeTooCrypto">M2Crypto</a> code hasn&#8217;t changed. The next M2Crypto release will add support for 0penSSL 1.0.</p>
<h3>Clients</h3>
<p>Checking the peer certificate&#8217;s hostname is still the weak point of the <code>ssl</code> module. The SSL version selection situation has improved slightly like I explained above. Othewise follow the example I wrote in 2008.</p>
<p>Again, the M2Crypto API hasn&#8217;t changed.</p>
<p>Lately I have been working with <a href="http://pycurl.sourceforge.net/">pycurl</a> at <a href="http://egnyte.com/">Egnyte</a>, so I decided to give a client example using that module.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> pycurl
&nbsp;
c = pycurl.<span style="color: black;">Curl</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
c.<span style="color: black;">setopt</span><span style="color: black;">&#40;</span>pycurl.<span style="color: black;">URL</span>, <span style="color: #483d8b;">'https://www.google.com'</span><span style="color: black;">&#41;</span>
c.<span style="color: black;">setopt</span><span style="color: black;">&#40;</span>pycurl.<span style="color: black;">HTTPGET</span>, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
c.<span style="color: black;">setopt</span><span style="color: black;">&#40;</span>pycurl.<span style="color: black;">SSL_VERIFYPEER</span>, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
c.<span style="color: black;">setopt</span><span style="color: black;">&#40;</span>pycurl.<span style="color: black;">CAINFO</span>, <span style="color: #483d8b;">'ca.pem'</span><span style="color: black;">&#41;</span>
c.<span style="color: black;">setopt</span><span style="color: black;">&#40;</span>pycurl.<span style="color: black;">SSL_VERIFYHOST</span>, <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">try</span>:
    c.<span style="color: black;">perform</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">finally</span>:
    c.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>I am not a big fan of pycurl due to difficulties getting it compiled and the non-Pythonic API. But it is based on the very powerful curl library, so it comes full featured out of the box.</p>
<h3>Other Resources</h3>
<p>Besides the Python crypto libraries capable of doing SSL that I mentioned in my <a href="http://www.heikkitoivonen.net/blog/2008/10/14/ssl-in-python-26/">SSL in Python 2.6</a> article, I have found pycurl. Another find in the Python crypto front is <a href="http://www.cryptlib.com/">cryptlib</a>. </p>
<p><a href="http://www.mikeivanov.com/">Mike Ivanov</a> wrote a great series about crypto in Python: <a href="http://www.activestate.com/blog/2010/03/python-crypto-state-art-part-2">part 2</a>, <a href="http://www.activestate.com/blog/2010/05/python-crypto-state-art-part-3">part 3</a> (link to part 1 seems to have rotted). Mike also produced a <a href="http://mikeivanov.com/pc/python-crypto.pdf">comparison of different Python crypto libraries</a> (PDF).</p>
<p>The future is also looking bright for the <code>ssl</code> module. Already the upcoming <a href="http://docs.python.org/dev/library/ssl.html">Python 3.2 ssl module</a> will include support for <code>SSLContext</code>s so that you can set options for multiple SSL connections at once, allows you to selectively disable SSL versions, and it allows you to check the OpenSSL version as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.heikkitoivonen.net/blog/2010/08/23/ssl-in-python-2-7/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Space-Time Tradeoff</title>
		<link>http://www.heikkitoivonen.net/blog/2010/08/22/space-time-tradeoff/</link>
		<comments>http://www.heikkitoivonen.net/blog/2010/08/22/space-time-tradeoff/#comments</comments>
		<pubDate>Mon, 23 Aug 2010 05:38:32 +0000</pubDate>
		<dc:creator>Heikki Toivonen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.heikkitoivonen.net/blog/?p=1123</guid>
		<description><![CDATA[It is a pretty common strategy in programming circles to make programs run faster by making them use more space (for example, by caching some results from long computations so they don&#8217;t need to be done too often). But there is also another kind of space-time tradeoff: something not very elegant is taking a little [...]]]></description>
			<content:encoded><![CDATA[<p>It is a pretty <a href="http://en.wikipedia.org/wiki/Space-time_tradeoff">common strategy in programming</a> circles to make programs run faster by making them use more space (for example, by caching some results from long computations so they don&#8217;t need to be done too often). But there is also another kind of space-time tradeoff: something not very elegant is taking a little too much space, but cleaning it up would take too much time and there are more important things to do. It occurred to me that I do this space-time tradeoff in my life outside of programming as well.</p>
<p>I have gathered piles and piles of once-important papers, magazines, books and so forth that I don&#8217;t think I will ever read. Likewise, I own a pile of clothes I will probably never wear again. I am sure I have lots of other things I basically never use, but I still have them stored somewhere, taking up unnecessary space. But if I wanted to get rid of all this stuff, I would need to spend quite a bit of time going through each potentially unneeded thing, deciding if I was ever going to use it, and if not, what should I do with it. So I reason that it is better to not worry about the unnecessary junk, as long as I have a place to put down a few important-for-now-at-least things&#8230;</p>
<p>Or it could just be that I am trying to rationalize being a pack-rat.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.heikkitoivonen.net/blog/2010/08/22/space-time-tradeoff/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bacon Rank Android App Details</title>
		<link>http://www.heikkitoivonen.net/blog/2010/05/13/bacon-rank-android-app-details/</link>
		<comments>http://www.heikkitoivonen.net/blog/2010/05/13/bacon-rank-android-app-details/#comments</comments>
		<pubDate>Fri, 14 May 2010 05:11:55 +0000</pubDate>
		<dc:creator>Heikki Toivonen</dc:creator>
				<category><![CDATA[Mobile]]></category>
		<category><![CDATA[android]]></category>

		<guid isPermaLink="false">http://www.heikkitoivonen.net/blog/?p=1096</guid>
		<description><![CDATA[Bacon Rank is currently my most ambitious Android project from UI and background processing point of view. It has custom UI controls and it deals gracefully with long running network operations. Let&#8217;s start with the custom SeekBar first, which is used to select the number of strips of bacon you ate. When you have a [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://baconrank.com/">Bacon Rank</a> is currently my most ambitious Android project from UI and background processing point of view. It has custom UI controls and it deals gracefully with long running network operations.</p>
<p>Let&#8217;s start with the custom <a href="http://developer.android.com/reference/android/widget/SeekBar.html">SeekBar</a> first, which is used to select the number of strips of bacon you ate. When you have a touch screen device, especially with no physical keyboard, you want to avoid situations where the user is forced to type anything. In my case <code>SeekBar</code> works great, since you can&#8217;t eat that many strips of bacon at one sitting. To draw the <code>SeekBar</code> with custom images I created <code>bacon_seekbar.xm</code>l in the <code>drawable</code> folder:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;layer-list</span></span>
<span style="color: #009900;">  <span style="color: #000066;">xmlns:android</span>=<span style="color: #ff0000;">&quot;http://schemas.android.com/apk/res/android&quot;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;item</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:id</span>=<span style="color: #ff0000;">&quot;@+android:id/background&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:drawable</span>=<span style="color: #ff0000;">&quot;@drawable/progress_mediumbacon&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;item</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:id</span>=<span style="color: #ff0000;">&quot;@+android:id/SecondaryProgress&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:drawable</span>=<span style="color: #ff0000;">&quot;@drawable/progress_rawbacon&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;item</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:id</span>=<span style="color: #ff0000;">&quot;@+android:id/progress&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:drawable</span>=<span style="color: #ff0000;">&quot;@drawable/progress_cookedbacon&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/layer-list<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>The <code>progress_*</code> drawables are PNG images.</p>
<p>In the main layout I use the custom <code>SeekBar</code> and set a custom thumb (a PNG image of a skillet):</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;SeekBar</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:id</span>=<span style="color: #ff0000;">&quot;@+id/SEEKBAR&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:layout_below</span>=<span style="color: #ff0000;">&quot;@id/BACON_STRIPS&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:layout_width</span>=<span style="color: #ff0000;">&quot;fill_parent&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:layout_height</span>=<span style="color: #ff0000;">&quot;wrap_content&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:max</span>=<span style="color: #ff0000;">&quot;20&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:progress</span>=<span style="color: #ff0000;">&quot;0&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:secondaryProgress</span>=<span style="color: #ff0000;">&quot;0&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:paddingLeft</span>=<span style="color: #ff0000;">&quot;32px&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:paddingRight</span>=<span style="color: #ff0000;">&quot;32px&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:progressDrawable</span>=<span style="color: #ff0000;">&quot;@drawable/bacon_seekbar&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:thumb</span>=<span style="color: #ff0000;">&quot;@drawable/skillet&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000000; font-weight: bold;">/&gt;</span></span></pre></div></div>

<p><code>SeekBar</code> has three states (if you count background), but I am really just using two. The weird part is that I thought I would use <code>background</code> and <code>progress</code> states, but I could not get that to work. Instead, I am using <code>SecondaryProgress</code> as background, and background is not visible anywhere. In <code>onCreate</code> I set up the <code>SeekBar</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">mSeekBar <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>SeekBar<span style="color: #009900;">&#41;</span>findViewById<span style="color: #009900;">&#40;</span>R.<span style="color: #006633;">id</span>.<span style="color: #006633;">SEEKBAR</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
mSeekBar.<span style="color: #006633;">setOnSeekBarChangeListener</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
mSeekBar.<span style="color: #006633;">setMax</span><span style="color: #009900;">&#40;</span>PROGRESS_MAX<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>In <code>onProgressChanged</code> method I update the amount in the UI and that is about it for the <code>SeekBar</code>. I think it looks pretty nice, but it would be better if I could make it look more 3D:</p>
<p><a href="http://www.heikkitoivonen.net/blog/wp-content/uploads/2010/05/screenshot-blog.png"><img src="http://www.heikkitoivonen.net/blog/wp-content/uploads/2010/05/screenshot-blog-200x300.png" alt="" title="Bacon Rank Screenshot" width="200" height="300" class="aligncenter size-medium wp-image-1103" /></a></p>
<p>The trickiest part of the application was handling of the network activity while allowing for screen orientation changes. None of the tutorials I&#8217;ve read or the <a href="http://stackoverflow.com/questions/1111980/how-to-handle-screen-orientation-change-when-progress-dialog-and-background-threa">stackoverflow questions and answers</a> regarding this seemed workable (or maybe I did not understand them). The problem is this: suppose in your activity you start an <a href="http://developer.android.com/reference/android/os/AsyncTask.html">AsyncTask</a> for the network activity. This is what is actually recommended pretty much everywhere. But suppose your user then changes the screen orientation. By default Android destroys and recreates the current activity. Your<code> AsyncTask</code> is still going, but it does not know about the new activity, and your new activity has no knowledge of the <code>AsyncTask</code>. So what is the fix?</p>
<p>It turns out you can create a custom <a href="http://developer.android.com/reference/android/app/Application.html">application</a> object, which will be available as long as your process is running. So in your activity you can start the <code>AsyncTask</code> as before, but keep a reference to the <code>AsyncTask</code> in the application object. The <code>AsyncTask</code> needs a reference to the current activity to draw on the screen, which your activity keeps up to date. Basically set it on <code>AsyncTask</code> creation, null it during screen orientation and activity destroy, and restore when the activity is recreated. We also want to run an indeterminate progress indicator in the UI while network activity is going. In code this looks something like this (I&#8217;m omitting many irrelevant details):</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> BaconApp <span style="color: #000000; font-weight: bold;">extends</span> Application <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> BaconRank.<span style="color: #006633;">SyncTask</span> mSyncTask <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> BaconRank <span style="color: #000000; font-weight: bold;">extends</span> Activity <span style="color: #000000; font-weight: bold;">implements</span> SeekBar.<span style="color: #006633;">OnSeekBarChangeListener</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
    @Override
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onCreate<span style="color: #009900;">&#40;</span>Bundle savedInstanceState<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">onCreate</span><span style="color: #009900;">&#40;</span>savedInstanceState<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        requestWindowFeature<span style="color: #009900;">&#40;</span><span style="color: #003399;">Window</span>.<span style="color: #006633;">FEATURE_INDETERMINATE_PROGRESS</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// ...</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    BaconRank.<span style="color: #006633;">SyncTask</span> getSyncTask<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>BaconApp<span style="color: #009900;">&#41;</span>getApplication<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">mSyncTask</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">void</span> sync<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> action<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>BaconApp<span style="color: #009900;">&#41;</span>getApplication<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">mSyncTask</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>SyncTask<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">new</span> SyncTask<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">execute</span><span style="color: #009900;">&#40;</span>getUserAgent<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, mUserId,
                mBaconStrips.<span style="color: #006633;">getText</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>,
                action<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    @Override
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onSaveInstanceState<span style="color: #009900;">&#40;</span>Bundle outState<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">onSaveInstanceState</span><span style="color: #009900;">&#40;</span>outState<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        SyncTask syncTask <span style="color: #339933;">=</span> getSyncTask<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>syncTask <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            syncTask.<span style="color: #006633;">setActivity</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    @Override
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onRestoreInstanceState<span style="color: #009900;">&#40;</span>Bundle inState<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">onRestoreInstanceState</span><span style="color: #009900;">&#40;</span>inState<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        SyncTask syncTask <span style="color: #339933;">=</span> getSyncTask<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>syncTask <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            setProgressBarIndeterminateVisibility<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            syncTask.<span style="color: #006633;">setActivity</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    @Override
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onStop<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">onStop</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        SyncTask syncTask <span style="color: #339933;">=</span> getSyncTask<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>syncTask <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            syncTask.<span style="color: #006633;">setActivity</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> SyncTask <span style="color: #000000; font-weight: bold;">extends</span> AsyncTask<span style="color: #339933;">&lt;</span>String, <span style="color: #003399;">Void</span>, JSONObject<span style="color: #339933;">&gt;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">public</span> SyncTask<span style="color: #009900;">&#40;</span>BaconRank activity<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            mActivity <span style="color: #339933;">=</span> activity<span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setActivity<span style="color: #009900;">&#40;</span>BaconRank activity<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            mActivity <span style="color: #339933;">=</span> activity<span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> onPreExecute<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>mActivity <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                mActivity.<span style="color: #006633;">setProgressBarIndeterminateVisibility</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> onCancelled<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #666666; font-style: italic;">// mActivity cannot be null</span>
            mActivity.<span style="color: #006633;">setProgressBarIndeterminateVisibility</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            clearActivity<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">void</span> clearActivity<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #666666; font-style: italic;">// call in ui thread only</span>
            <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>BaconApp<span style="color: #009900;">&#41;</span>mActivity.<span style="color: #006633;">getApplication</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">mSyncTask</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>            
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> onPostExecute<span style="color: #009900;">&#40;</span>JSONObject result<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>mActivity <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #666666; font-style: italic;">// Update UI</span>
            <span style="color: #009900;">&#125;</span>
            clearActivity<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">protected</span> JSONObject doInBackground<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span>... <span style="color: #006633;">params</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #666666; font-style: italic;">// Do the network stuff</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>You will also need to specify the custom application object in the AndroidManifest.xml:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;">  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;application</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:name</span>=<span style="color: #ff0000;">&quot;.BaconApp&quot;</span></span>
<span style="color: #009900;">  <span style="color: #000000; font-weight: bold;">&gt;</span></span></pre></div></div>

<p>And that wraps the Bacon Rank presentation. If you know how to do anything I presented above in a better way, please leave a comment. The application is also localizeable, so if you want to translate the app into your language let me know.</p>
<p>If you did not read it already, you might want to read about the <a href="http://www.heikkitoivonen.net/blog/2010/05/11/baconrank-com-powered-by-turbogears-2/">application running baconrank.com</a>, the server the Android application talks to.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.heikkitoivonen.net/blog/2010/05/13/bacon-rank-android-app-details/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 2.033 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2013-05-18 17:40:16 -->
