Saturday, June 23, 2012

Android Development: How to get GPU Acceleration for your AVDs

I was quite excited when I first read the news that the Android Emulator now supports using your PC's GPU for better graphics performance.  Trouble is, the aforementioned announcement doesn't contain any information on how it works.  I only discovered the answer thanks to Google's revamped developer site, wherein I stumbled across an emulator setup guide I had never seen before (I'm assuming that it actually was there before, and that it isn't a brand new page.  I could very well be wrong on that).

Anyway, the answer is found in the settings page for your virtual device. In the hardware section, you can click "New", and choose the "GPU Emulation" property.  Set it to yes, and your graphics card will be put to work (provided it is supported; I'm not sure how well it works in all environments).

Click the 'New' button in the 'Hardware' section, and you'll be able to add GPU emulation as a property (It's shown at the bottom of the property list here).
So far, the results are impressive.  The virtual device still takes a while to load up (though not as long as it did when I first tinkered with the SDK, years ago), but once it's on, it is very smooth and responsive, enough so to make it worthwhile for testing.  This could make it much easier to test future projects on multiple device types.

The guide above also explains how to configure Virtual Machine acceleration, using the VM extensions  supported by modern processors.  This is another welcome feature for improving emulator performance, but it looks more complicated to setup.  Namely, you have to enable the VM extensions for your CPU via the BIOS, and install extra virtualization drivers.  The drivers are the real showstopper, as the guide warns that they can conflict with the drivers for other VM software like Virtualbox.  The fix is to only enable one set of drivers at a time - this is easy enough in a *nix environment, but I'd have to go and find out what Vitrualbox installs.

Once you've got your drivers under control, there's one last caveat; to use VM acceleration, your virtual device has to be running an x86 CPU, rather than the traditional ARM chip.  This isn't really a problem - Intel has already put out an x86 based phone, and the support is there.  You just have to remember to take the extra step, because these AVDs go to ARM by default.

If I dip my toes into this CPU virtualization, I'll come back here with my findings.

Sunday, June 17, 2012

Notepad App: The Rest

With the Scratchpad finished, the next step was to get the regular notepad functionality working.  Since I already had a working example, all I had to do was fit it into my existing codebase.  This turned out to be fairly easy, and I had a half-working example after no more than an hour's work.  Getting it working well was another matter entirely.

For one, the text on the main screen was small, and only the text itself was responsive to touch input.  If the title of a note was small, it was almost impossible to open (and if there was no title, it was completely inaccessible).   This fix taught me just how important it is to understand the built in Android layout rules.  The "wrap_content" rule, for instance, can be a bad choice for setting the width of a view. So can "match_parent" if you aren't aware of what the parent view's width is set to.  This is yet another area in which blindly following sample code can get you in trouble, when all of a sudden your GUI is lined up all wrong and you don't know why.  I ended up re-evaluating the width and height of every View in every XML file in the app, since this forced me to justify each and every setting.  By the end, I had everything looking the way I wanted it, and more importantly, I understood why.

My initial porting attempt also broke a small (but handy) feature from the sample Notepad app; if there were no saved notes, a special "no notes" message was displayed instead.  In my app, however, this message was displaying even when there were notes present.  It turns out that this feature requires your app to be designed in a very specific fashion, which happened to be the case for the sample app, but not mine.  Specifically, the Activity in question needs to:

  • Subclass Android's ListActivity class.
  • The layout file associated with the Activity needs to contain one ListView and one TextView, and they must be id'ed using two of Android's standard View names - "list" and "no_notes".

Looking at my app, I knew that my layout file used different id names, and that my class only extended  Activity. An easy fix to be sure, but there was another problem - could I still cram the Scratchpad 
button onto the page?  If I added it to the layout file, would it display?  And even if it did, would the ListActivity accomodate the code responsible for handling click input?

The answer to both of these questions is "yes" and "yes".  By using a ListActivity, you benefit from having a built-in ListView object to use, but you aren't married to it.  Remember that you can technically associate any layout file to a ListActivity.  It helps if some of the Views defined in the layout are structured in such a way to work well with the class, but even then you can still add more on top of it.  Then, once you add extra buttons and gizmos, you simply write a click handler for each one. For me, this translated into an extra layout entry (for the Scratchpad button), and a single, small click handler.  Nice and easy all around, and I learned a ton about how views and activities relate to each other.


After that, it was just a matter of making a few final touch ups, such as having the cursor appear at the end of the title when opening a note, and giving notes a default title when none is entered. All told, this phase of the work took almost as long as the last, but I got far, far more done.

I'd like to end this entry with a list of additional lessons learned.   All told, this was a very rewarding experience, and I feel more motivated than ever after achieving this small success.
  •  For the first time, I used version control on a personal project.  I'm using git, as I'm used to it from work, and it worked like a charm.  When I tried to refactor the app to use a ListActivity, I created a new branch: it was nice to know that, should it not work, I could revert back to a working state.
  • I'm planing on going back to this app at a later date, to make some improvements. Specifically, it could use better error handling, and it would be nice to have more flexible controls for adding/deleting/editing content.  Perhaps even a home screen widget for displaying the Scratchpad.
  • I ran into an issue using StringBuffer; namely, I was trying to reuse the same StringBuffer instance without cleaning it out, so it kept preserving its previous content.  Ideally, what I should have been doing was creating a new object every time, but sometimes I still think like a C coder, and I considered that a waste of memory.  Yeah yeah, there's garbage collection, I know, but wiping the buffer was trivial, and now I feel like I can go to sleep tonight.
  • Next up, a tasks app.  It'll be far more complicated, but even more useful too.

Saturday, June 16, 2012

Notepad App: Scratchpad

I've finally a useable part of my personal app.  The Scratchpad function is working fully.

I made a serious mistake when working on this part, by trying to store the Scratchpad data in a SQLite database.  Such a DB makes sense when you are storing multiple notes, but the Scratchpad is just one big note, a text dump for storing quick thoughts that I don't want or need to create a full, separate note for.  There's no need to wrestle with database queries and row integrity.  I lost several hours struggling to get things working, to the point where I almost gave up.

Thankfully, I sat back down and researched alternative storage methods.  After all, this kind of data could easily be stored in as a text file, and as it turns out, Android has tools for doing this.  You can create storage files that are viewable and readable only by the app itself.  Using this technique, I got the Scratchpad working very quickly, and while I am happy it works, I'm also more frustrated with the fact that I'll never get those wasted hours back.

This reveals a major flaw in my skills as a programmer.  I rely on sample code too much, to the point where it holds me back.  I needed to store data; what I should have done is look through the reference documents for ways to do this.  Instead, I looked through the samples I had previously read through.  Since all of these samples were dealing with ListViews, they all used SQLite tables.  It wasn't the only storage choice available, but it was the only one I was exposed to.  Thus my tunnel vision set in.

The other problem with using sample code is that sometimes the only thing it can teach you is how certain parts of the API work within the context of this specific example.  Unless you can read the code and understand how to use a featured method  in any given situation, then you don't really understand how to use it.  If you then proceed to copy and paste that code into a completely different context, what will you do if it breaks?  Scramble, of course, because you don't know enough about how it works.

I made these mistakes with the Scratchpad, and for my own sake, I need to learn from them if I am to get the remainder of the app completed without experiencing this level of frustration.


The Moral of the Story: Use sample code to get a feel for how a complete program reads and flows.  But when it's time to do something yourself, figure out what it is you want to do, and look through the API to find pieces that will help you do that.  Work with them until you find out what it really does, and if it isn't suiting your purposes, start looking again.  By the time you have a working prototype, you will be able to explain why it works (and if it turns out there's a better way you could have done it, don't worry.  That can come in a new version, when your skills have improved).

Notepad App: Intro

My first attempt at an Android App is to make a notepad application.  As it turns out, the Android sample code has a fully functioning notepad in its sample code folder.  It's simple, but if all you want is to write and save notes, it's perfect.

However, I want to do slightly more than that. Namely:

- I want to be able to write individual notes, with titles, that I can save (this is what the Android sample project already offers).
- I want to have a single, giant note, called the "Scratchpad", which I can access quickly, and fill with quick bits of text.  The point here is not organization, but to allow me to just get things down before I forget.

In theory, this should be a simple job.  Just take the existing example, add a new button on the screen for the Scratchpad, and an additional, super basic text editing window for modifying it.

Let's see just how simple it will be for me in practice. Consider this a developer diary of sorts.