Monday, May 27, 2013
Friday, March 1, 2013
When you're using an Android library project as the base code for multiple projects, it's handy to rely on resource overrides for configuration parameters. For example, you could use a strings resource file that points to different URLS, etc. While doing this is quite handy, you must also consider that resource files are very easy to extract using apktool, so if you are concerned about keeping any of this configuration data secure, you're going to have to take some extra precautions.
Our high level strategy will be to do the following.
- Encrypt our application license key (obtained via the Google Developer Console) using a hardcoded encryption key (think password).
- Base64 the encrypted 'cipher' text.
- Use this encrypted/base64 encoded value in our strings resource file.
Since it's hard to get around hardcoding your secret key (the keyBytes in our sample code) using this strategy, it would be naive to assume this is 100% foolproof. A persistent minded individual could still decompile your app, discover the byte array you used for encryption, and then reverse the entire process. Your job is to make this as difficult as you can reasonably make it. You could store your key in multiple byte arrays and combine them when needed, for instance. I won't go into specific methods here, but the point is to be creative. Using a code obfuscation tool such as proguard will help, or at the very least use non-obvious/misleading method names to perform these operations.
Wednesday, March 2, 2011
I just read via engadget that Google is giving away Xoom tablets to attendees at the GDC. Originally, giving away free hardware was a great way to get devs to play around and build cool apps, but this cute gimmick has run it's course. People now expect to get free hardware from Google, and since the value of the hardware tends to exceed the ticket price of the conference, everyone and their mother are signing up.
I had planned on going to Google IO this year, and was patiently waiting for registration to open. I made the mistake of walking across the street to Panera for lunch with some co-workers, and by the time I got back registration had already opened and closed. Who cares you say? Maybe I'm just bitter because I wasn't one of the lucky few that made it.
Sorry, but there is more too it than that, dev conferences are supposed to be for developers. It's a chance to learn new stuff and get some important networking done. The job I have now at TuneWiki, in fact, came from a random encounter I had during a lunch break at a previous Google IO. Signing up for a Google IO event, should not be the online equivalent of going to Walmart on Black Friday.
Yes, I'm also aware of the Google IO Pre-Sale VIP list, which supposedly was to give deserving developers a guaranteed spot at the conference. Except that it failed, miserably, imo. Using myself as an example, I attended the very first Android event on the Google campus. I worked on two android projects that won top 10 placement in the first ADC (find someone else who can claim that). I attended the first device readiness event before the G1 was released. I sat front row at the G1 announcement press-conference as a special guest of T-mobile. My current work efforts not only include TuneWiki, but also the media player that's baked into every motorola device (before US carriers replace it with their crapware). Despite all this, I did not receive a VIP pre-sale invite. And if I didn't get an invite, you can bet your ass there are plenty of other deserving developers who didn't either.
In short, Google, I am disappoint.
UPDATE: For the record, I already have stacks of android devices on my desk, including unreleased evaluation devices, so anyone who thinks that I'm butthurt over not getting a tablet is only re-enforcing my point. People are now assuming getting a device is the reason I want to go to these events.
Sunday, May 30, 2010
AsyncTask is a fine API, it's been said that it "holds your hand", and makes performing background operations painless. It pulls this off so well in fact, that I see people overusing it in situations where it's not really appropriate.
It's particularly unsuited for situations when you have a multiple tasks to perform concurrently. Imagine an Activity that needs to download about 30 small images from a remote server, and update the UI as these become available. AsyncTask uses a static internal work queue with a hard-coded limit of 10 elements. That means if you were to create an AsyncTask instance for each image, the work queue would quickly overflow and many of your tasks would get rejected. The best solution in this case is to create your own ThreadPoolExecutor instance that uses a queue that's large enough to hold all your tasks, if you need an unbounded queue, a LinkedBlockingQueue will work just fine.
Another severe limitation is that an AsyncTask can't survive your Activity being torn down and recreated on the other side. Even if you pass it to the new instance via onRetainNonConfigurationState, the internal Handler inside the AsyncTask is still going to be stale and it's not going to behave correctly. This is important to consider, and the Android documentation makes no mention of it all. I've already blogged this scenario in detail, so I won't flog a dead horse here.
There are a few other minor issues, such as the fact that you can't change the background threads execution priority. It's hard-coded to a low priority, which granted, is the sensible default. Also, exception handling is not very well supported.
So just to reiterate, AsyncTask is a nice API, but you should understand it's limitations and apply it appropriately. If you're serious about writing mobile apps, then you're going to need a few more tools in the toolbox to get the job done.
Saturday, May 22, 2010
Android 2.2 is the most significant upgrade to the Android OS that I can remember. Chock full of new goodies for both users and developers.
I thought I'd just do a quickie post to highlight the features for developers I'm most interested in.
1) Android Cloud to Device Messaging - this is one feature that's been sorely lacking from the Android platform and it's a welcomed addition. The demo at Google IO demonstrated how you can push a message to a device in real time, and have it fire off an Intent which can kick off any number of interesting and yet to be dreamed of services. This also opens up a new way for devices to communicate with each other in real time over the internet, I expect interesting things to come of this.
2) Android Application Error Reports - logging exceptions remotely that occur on a users device is a very useful thing and every mobile company I've worked at has done this in some form or another. The typically way to do it is to override the default exception handler and replace it with something that will log the exception. I myself just started building a new GAE project for this a few weeks ago http://github.com/jasonhudgins/Remote-Incident-Logger. The initial usefulness of this will be somewhat limited, due to the fact that many devices are going to be running older versions of android for the foreseeable future.
3) Stagefright media framework - I don't know much about Stagefright, I'll admit that right off the bat, what I do know is that I'm dreadfully tired with the limitations of the current MediaPlayer framework, and I'm really hopeful this can serve as an improvement / replacement for the API's we've been using up til now.
And lastly, I'd also like to mention the new support for Android Library Projects that are available in the newest SDK tools (SDK Tools r6). We will finally be able to share common resources between multiple projects, and since it's just build time magic, these new library projects are going to be backwards compatible with older platform versions.
Wrapping up, I'm really excited about android 2.2. Google has really raised the bar with this release, and it's going to be interesting to see how other mobile technologies evolve in response to this.
Wednesday, March 31, 2010
I came across another ProgressBar tutorial a few days back posted on helloandroid.com, and while it's certainly good enough to get someone started, it doesn't really go into any detail about how your non-ui thread should work, and how it should gracefully handle Activity restarts and what not. It uses a message handler to send notifications to the ui thread, but what if the Activity is paused and the message handler becomes stale?
So I'm taking this as a good opportunity to follow up on my previous Rebel Without A Context post.
The code is fairly short, so I won't go into a line-by-line explanation of it, but the general idea is that you have your own Thread implementation that maintains state, and you pass it from the old activity to the new activity via onRetainNonConfigurationInstance(). Also rather than updating the UI directly by sending a message from the background thread, the UI thread actively polls the background thread every 50 milliseconds with a handler loop, which updates the progress bar as necessary.
With this kind of approach, you can for example, flip orientations back and forth gracefully with no stale handlers or leaky window exceptions.
Saturday, March 20, 2010
In a previous post entitled, HTTP connection reuse in android, I tossed out a code snippet for an HttpClientFactory that would spit out a DefaulHttpClient implementation suitably configured for re-using already open HTTP connections to serve multiple requests across multiple threads.
My hasty implementation from that post leaves a few things to be desired. Primarily, it's a singleton implementation which can lead to some problems. Since it's effectively a global resource, doing things like modifying the time out value, or forcibly closing the connection manager (as one commenter pointed out), could lead to the HttpClient to be in an invalid or undesired state when reused at a different time or a different part of your application.
So here's a simplified version without the singleton garbage:
The ideal place to use something like this is when you want to download multiple items from a single remote source, for example, if I needed to download a bunch of thumbnails to be displayed in a ListView, I could have a thread pool downloading images concurrently and all sharing this one HttpClient instance, reusing HTTP connections as they became available (all managed inside the HttpClient)