Archive for the ‘Android’ Category

9-Patches Explained

One of Android’s most well-known points to consider in application development is the requirement to support a variety of different screen sizes and orientations in an application. The SDK is full of documentation and tools on how to help the developer best accomplish this goal; one of these tools is the 9-Patch creator.

The 9-Patch is a PNG image with some coding added that allows the Android system to determine how the image can be stretched and contorted to meet the specific layout constraints during use (like fill_parent and wrap_content).  It does this by taking a predefined PNG image, and allowing the user to define a 1-pixel border around the image in locations where stretching can occur.

Creating a 9-Patch

  1. Navigate to the tools/ directory of your SDK from a command-line.
  2. Run draw9patch and a window will appear.
  3. Drag and drop and PNG image into the application window
    • The image will appear with a blank 1-px border around it
  4. Add stretchable regions by clicking on pixels in the newly created blank area (you will see black mark appear for each selection)
    • Remove any mistakes by holding the Shift key and clicking on a marked pixel
    • See below for more on this

9-Patch Theory

The 9-Patch gets its name from the fact that the overlay created breaks the image up into nine defined regions, organized similar to tic-tac-toe.  Each region has specific stretch properties:

  • Corner Regions (A,C,G,I)
    • These regions are fixed and nothing inside them will stretch
  • Horizontal Sides (D,F)
    • The pixels in these regions will stretch vertically when necessary
  • Vertical Sides (B,H)
    • The pixels in these regions will stretch horizontally when necessary
  • Center (E)
    • The pixels in this regions will stretch in both horizontal and vertical directions equally

Draw9Patch

The draw9patch tool allows the user to define two pieces of data by applying marks on the image border:

  • Stretchable zones
    • The portions of the image that are to be fixed or stretched when the image must fill or wrap in layout
    • Created by marking border pieces on the TOP and LEFT of the image
  • Content area
    • The area portion of the image where content is to be inserted (generally text or something applied via the android:src xml tag)
    • Created by marking border pieces on the BOTTOM and RIGHT of the image

As an example, below is what a basic patched graphic will look like inside the draw9patch tool.  The green regions define the patches that will stretch either horizontal or vertical.  The pink patch is a fully stretchable patch.

Original

Patched

You can see how the colored regions map to the example grid shown above.  This is a simple example, but the user can create multiple regions in the same image like so:

Now we have an image with multiple fixed and stretchable regions.  Again, pink will stretch in both directions, green in one direction, and the rest of the image will be fixed.

A Word About Content

Defining the content area gives the user the ability to assist Android in providing the proper location where source content (text, other images, etc.) are placed when this image is a background or other content wrapper image.  Think of the standard Button as an example.  When a user defines android:text (of android:src on an ImageButton), this is the button content.  That content is laid out inside of the content area that was defined in the button background image (a 9-patch, by the way).

With our example, if I define a solid mark across the bottom and right of the image, stopping just short of the rounded corners, a content area will be defined as shown in this preview pane:

Tricks of the Tool

  • Show Patches
    • Turn on the visual assistance of the green/pink patch locations
  • Show Content
    • In the preview pane, highlight the content section that exists in each orientation
  • Show Bad Patches
    • Allow draw9patch to evaluate whether you might be causing trouble by defining a stretchable area that includes components (like a piece of text or a gradient) that won’t always stretch consistently.  The “bad” patches are enclosed in bright red borders.

Android Layout Relationships

Developing UI layouts for Android is an experience unlike any other.  I have developed for both desktop and mobile on a variety of platforms, and the XML structure that Android uses is quite unique.  This can bring with it some issues and challenges as it runs contrary to the way many people think about designing their UI.  Today, I’m going to make some comments on questions that I see constantly regarding the XML keywords most commonly misused in creating layouts.

I’m going to focus on developing using XML, but the same rules apply when creating LayoutParams in code.

Me Or My Parent?

When laying out elements (or widgets) on the screen, it usually doesn’t take long for people to realize that there are two of many of the basic parameters associated with size and location.  Options like width, height, and gravity have parallel values named layout_width, layout_height, and layout_gravity; so what gives?  Parameters with the prefix layout_ are actually instructions that are to be passed to the PARENT of the object that they are placed on, while all other parameters are passed to the object itself.

This can be a source of confusion even when you want to do something as simple as center some text, so let’s look at an example.  Imagine we have a simple layout like the one listed below:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:text="My Text Content"
  />
</LinearLayout>

We placed the constraint layout_gravity=”center_horizontal” so that the text would be centered on the screen, but if this layout gets rendered, the results are not as expected!  Why?  Well, in the example the TextView told the following to its parent LinearLayout:

  • Make me as wide as you are (layout_width=”fill_parent”)
  • Make me just tall enough to fit the text inside (layout_height=”wrap_content”)
  • Lay me out centered horizontally (layout_gravity=”center_horizontal”)

Points #1 and #3 are actually in direct opposition to each other.  The TextView has asked to be centered within the LinearLayout, but also be just as wide (so there is really no room to center it).  What we really wanted to do was to either:

  1. Tell the TextView ITSELF to center its own contents horizontally within the view bounds
  2. Tell the TextView to be JUST as wide as its text, and them center the whole view horizontally in the parent.

Example Fix #1

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal"
    android:text="My Text Content"
  />
</LinearLayout>

Example Fix #2

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:text="My Text Content"
  />
</LinearLayout>

Bottom Line: Remember that any parameter that starts with layout_ is actually an instruction for the parent view, and not the view where it is located!

Android Lifecycle Callbacks

I hear people say a lot that the lifecycle callback functions in an Android Activity are confusing.  Their names address the events that can occur from a memory management perspective, but they don’t directly address things that the developer really pays attention to.  Things like “when is the view done loading into memory?” and “when is the view visible to the user?”.  I wanted to write a quick post to address this, because in many cases the best callback to address these issues is not located in the standard set.

The standard Activity callback functions are onCreate(), onStart(), onResume(), onPause(), onStop(), and onDestroy().  Most Activity implementations will cycle through these functions, in order or with a few small internal loops, from one end to the other.  The developer documentation on this (the link above) is good, but there are actually some hidden gems inside of the ActivityGroup documentation as well.

Mapping to More Useful Events

Here is a simple list of common things I see most often and where the best place to implement them would be in an Android Activity:

  1. When should I close/unload/finish resources the visible view requires?
    • onPause(): This method is the only one that you can be relatively guaranteed will be called every time.  In many situations, onStop() gets skipped, and it is usually too late if you wait for onDestroy().
  2. When do I know the Activity is active and ready to process again?
    • onResume(): This method, again, is a sure bet callback when the Activity is coming back to life.  Other methods, like onStart() may be surplanted by onRestart() depending on the startup conditions.
  3. When do I know the Activity is actually visible to the user?
    • onWindowFocusChanged(boolean hasFocus): This is one that is slightly outside the normal flow, but it is the best choice.  Trying to implement changes that are dependant on the Activity being visible in earlier callbacks like onResume() provides not guarantees of visibility.  In most cases, onResume() is too early and you may experience flickers during the transition.  hasFocus will (of course) be true when this is called as part of a reappear event.

More About onWindowFocusChanged()

The Android documentation describes this as the best method to use when determining when the Activity becomes visible or invisible to the user.  However, because it is not part of the normal lifecycle event flow, there are times when this function will be called that do not have to do with the Activity view appearing/disappearing during creation/destruction.  This method will also be called when temporary interactions like dialogs come up in front of the Activity.  This may be something to keep in mind as your implementation may be affected by this subtle difference.

Editorial: Your Reviews May Be Hurting You

Normally, I target developers in my posts, but today I had a special message that I wanted to send out to the user community.  I’ve noticed a trend over the past year that troubles me some about the way users are using their reviewing power in places like the App Store or the Android Market.

Users, the power you’ve been given to review mobile applications carries more weight than I think many of you give it credit for.

The consequences of an application review should not be taken lightly.  Believe it or not, other users do look at an app’s comments (or at least the top five at the time) and it’s current rating.  This can be a good thing, but it behooves me to point out that there are certain things that do not belong in reviews as they can prematurely cripple and application’s, or its developer’s, success.  Flagrant user of 1 star ratings for certain reasons will end up hurting the user community if used improperly, because many of the developers will choose not to develop more apps or make updates to those they’ve already published.

Here is a list of things that I believe low ratings and review comments SHOULD be used for:

  • Lack of developer feedback
    • I 100% agree that if you contact a developer with a question on an application, and get no response within a few days, you have the right to rate low.  Active applications need developer support.
  • Poor application quality
    • Try to distinguish poor user experience from a missing feature.  Just because an application doesn’t have a feature you think would be cool, doesn’t mean it is somehow broken.

Which brings me to things low ratings SHOULD NOT be used for:

  • Feature requests
  • Bug reports

A good developer enjoys hearing feedback about their application, and ways that they can improve the user experience in future releases.  This is why application markets provide developer contact information, so you may contact them directly with this type of feedback.  The salient point here is to give the developer(s) an opportunity to support you first.  Your helping them by letting them help you.  Often, a missing feature isn’t missing…just hidden.  By contacting the developer, you’ve learned where the feature is, and they’ve learned it needs to be more obvious where to find it next time.

The same goes for bugs.  App development is a small-scale business oftentimes, and developers can’t be as thorough with software testing as we all would like.  So, sometimes the user community ends up becoming beta testers on the first 1-2 releases of an application.  Again, direct contact will get these issues solved more quickly.  You will most likely be waiting longer if you post a bad review and expect that the developer saw it.

So, I guess the bottom line here is open dialogues with the app developers and, in the long run, you’ll be glad you did.  If the developer ignores your requests, then use that veto as it was intended.  Developers who ignore their users don’t have a place in this community anyway, in my humble opinion.

Don’t Get Lost! Tag your Comments!

Project Management, like version control, is something every developer should always be doing at some level in their work…period.  Regardless of the size and scope of a project, basic task management keeps things moving in the right direction.  However, I’m not saying that this should require some elaborate process either.  Oftentimes, a complex process can drive efficiency into the floor.  There is a common standard among major Integrated Development Environments (IDEs) that allows a developer to do a little bit of their own “in situ” project management using code comments…and I believe that this feature is drastically under-utilized.

These comment tags are recognized by IDEs and can be used to quickly and effectively build simple To-Do lists to help you complete all your objectives, or even just place markers in the source so you remember where to go back to.  Because of the scope of my recent work, and of this blog, my examples will focus on Xcode and Eclipse.  However, the general principle applies to many others out there.

Creating Comment Tags

There are two common keywords that work across IDEs: TODO and FIXME.  By placing comments like the following in your code, your on your way to managing what you need to do next, and where you need to do it:

// TODO: Add a method to handle incoming floats
// FIXME: The app crashes here when releasing the object

Placing these at the location where they are relevant will save you time and headache in situations like these:

  • Picking up where you left off the day before
  • Marking a location in a file when you have to move to another while tracing
  • Fleshing out stubs (start with a list of TODO comment before you write any code)

While this is a nice and simple procedure to follow, its the IDEs reaction to these that really makes them useful…

Xcode

Xcode recognizes the following tag styles in comments:

// TODO:
// FIXME:
// ???:
// !!!:

Note the colons on the primary tags, because Xcode needs them.  Notice also that there are two more generic tags that can be used to further subdivide your task listings (??? and !!!).  With these tags in your code, Xcode helps you out by placing markers in the file listing (where you also find your #pragma mark statements).

Each tag is organized underneath the method where it is located.  You may also choose to group your tags at the beginning of the file, as was done in the example above.  This cleans up the listing and puts all the tags in one place, but you don’t gain the ability to click and be transported to the relevant location.  It’s up to you!

Eclipse

Eclipse recognizes the following tag styles in comments:

// TODO
// FIXME
// XXX

Note that Eclipse provides one more tag to further assist you in subdividing your tasks (XXX, which must be capitalized).  With these tags placed in comments, Eclipse does three things for you:

  • Include a blue marker on the scroll bar in the source view (in the same location as yellow markers for warnings and red markers for errors)
  • Include a clipboard task marker on the left bar in the source view
  • Provide a Tasks View where you can view all active tags in all the files of your project at one glance.

The scroll bar marker feature is what makes using TODO or XXX tags as placeholders useful.  You can tag a location, move down to a method you need to finish, and then pop back to where your tag is.

The Tasks View may not be visible by default in Eclipse, but can be brought up from the Window -> Show View -> Other… menu (there is an option called Tasks).  Here you will be presented with a table that points out each tag and its location.  FIXME tags are marked with the exclamation point by default as well.

For the same reasons that single developers should always use version control, basic management of your tasks is crucial to happy and sane development.  In my opinion, this is a great start and it doesn’t get any simpler than this.

Android Dialog, or is it?

We’re all familiar with the concept of providing a temporary modal view to the user in an application for the purposes of notification or basic data entry. In the Android framework (as in many computer systems) a class is provided to the developer to create and maintain these views called a Dialog. This class is then further extended for you to make some convenient versions that allow entry of date/time information and make basic list selections (AlertDialog, TimePickerDialog, etc.). These classes work really well, and I would encourage you to leverage them whenever possible.

But what if you want to use the Dialog interface, but you have some custom data entry needs? Android makes it pretty simple to extend the base Dialog class and create custom behavior with a custom layout, and many people would consider this as the next logical option if they can’t solve their problem with one of the canned Dialog solutions. I’m here to tell you today that there is a better way.

The Problem

There are some subtle, but fairly major issues with the custom Dialog classes and state persistence. By design, the Dialog does not have the same functionality available to it as the Activity for life-cycle management. In particular, this includes managing device orientation changes, which (by default) completely breaks down the Activity and rebuilds it for a new configuration in Android. This is exacerbated by the realization that, in many Android devices, rotation is required EXTREMELY often after an entry dialog is shown because the user will want access to the keyboard to enter the data! If you’re dialog doesn’t rotate, your app is broken to the user.

So what’s the issue?  Do some experimentation with this and monitor LogCat some day.  As soon as you do an orientation change with an active dialog, you will get an android.View.WindowLeaked exception from the WindowManager.  This occurs (usually) because of reference conflict between the new activity that gets created, and a reference existing to the previous version of the dialog when you try to show it again.  This is actually pretty difficult to manage, even with managed dialogs using the Activity (although, here’s a hint: dismissing a dialog and destroying it are not the same thing). The canned dialogs available in the framework do not have this problem, which is why I mentioned using them whenever it fits.

The other “problem” with this implementation is that the Dialog class doesn’t get a passed Bundle or other framework inside of which to persist data (like anything the user STARTED to do before they rotated) like the Activity does.  This means a lot of passing data back to the calling Activity so it can manage the persisted data.

…This is all doable, but inefficient.

The Solution

Short Answer: The Dialog Theme for the Activity class.  Personally, the only thing that I REALLY like about the dialog class itself is the presentation method.  I like how it partially covers and dims the current activity which, conceptually, links it to the Activity in the user’s mind.  But everything else on the back end is MUCH better handled with an Activity:

  • startActivityForResult() and finish() are simple replacements for showDialog() and dismiss()
  • Data can be passed to and from the modal session using Intents (a great habit to get into anyway)
  • All the state persistence exists in the framework to handle rotation, like onSaveInstanceState() and the passed Bundle

Plus, creating an Activity class isn’t any more work than a custom Dialog.  Both are going to need the Constructor ( or onCreate() ) to call up super and then set the view to a custom XML layout file to set themselves up.

So the only missing piece is the Theme.  The one extra thing that you must do when you create an Activity instead of a Dialog is you must declare it in your Manifest so the system knows it exists when it comes to things like Intent resolution.  Coincidentally, the Manifest is also where you would set the dialog theme.  Take a look at the example below:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    ...>
    <application>
        <activity android:name=".HomeActivity">...</activity>
        <activity android:name=".NiceDialog"
                     android:theme="@android:style/Theme.Dialog">...</activity>
        ...
    </application>
    ...
</manifest>

Here, the Activity NiceDialog has been skinned to look just like a dialog would using the theme attribute. It now will wrap the content tightly and only partially cover the view of the calling Activity. Now the user is none the wiser, and you get all the benefits of Activity life-cycle management from your custom Dialog.

Editorial: Why Android Deserves Your Attention

I’ve read an increasing number of articles on the web recently from people who fervently believe that the Android platform is dead before it ever really got started. The common mantra going along with this is that Android is late to the party, and they didn’t bring anything new with them. First of all, I’m not sure how anyone getting into the game at this stage could be considered late, as the smartphone market is still quite infantile and rapidly developing…but I digress. Personally, I am very surprised by this perception, and have to wonder why the (mainly) iPhone community is so quick to attack?

I am a daily user of both the iPhone and Android platforms, and develop applications on both platforms as well. There are things about both that I love, and there are things about both that I hate; both as a user and developer.  I’m not the expert, and this is not an exhaustive comparison, but here are reasons that I believe Android deserves your attention (“you” being the developer) and why it is not dead…even if it doesn’t doesn’t immediately become king.

For context, as I’m writing this the latest software versions in the market are Android 2.1 and iPhone 3.1.2

The User Experience

There are some feature that Android provides to the user that the iPhone will need to incorporate eventually, in my opinion.  And I’m discussing them from a user perspective (not technical discussions of memory management, code efficiency, etc.)

  • Customizing Home Screen (Widgets)
    • The mobile user has severe A.D.D.; myself included. The faster the relevant content arrives to me, the less annoyed I am at how long I had to wait.  Checking the basics, like the Top 10 on my To-Do list or my next upcoming appointment, should not require me to run each application individually.  With Android, that data can live on my home screen in the form of widgets, and I can view it all right on the desktop (background services help a lot with this also, but we’ll get there).  And the data is REAL, it is not an image file stored and plastered as wallpaper.
  • Activity Stacking
    • My brain (and my life) works a LOT like a stack.  Often, what I am working on currently has something pushed on top of it that requires attention.  When I am done with that higher priority item, I need to step right back to doing what I was beforehand.  The Android concept of working follows this paradigm very well.  If I’m working in an application and need to send a quick email, I can bring email up on top of my current activity and do what I need to do.  After I am done with the email, I can go back to my previous activity and it is uninterrupted.  The same holds true if I get interrupted by a text message or other priority notification, I can load this activity ON TOP of what I was doing.  The tag line here is that I don’t have to close my old thoughts to start a new thought.

The Developer Experience

From the developer perspective, Android offers some neat opportunities as well.

  • Background Processing (Services)
    • Last year, when Apple announced that Push technology would be available to the iPhone, there was an uproar of excitement.  Suddenly, applications could grab the user’s attention without the need for the application to be running.  Push technology definitely has it’s place, but I do not believe that it can ever truly replace a background service in all instances.  Sometimes, developing a complete back-end server application and connecting with the Apple service is just too much overhead to put in to a project that just needs a method of notifying the user or doing simple work in the background.  Mobile devices may be resource constrained compared to the desktop platform, but I shouldn’t be afraid to run a few concurrent processes locally.  Shoot, I can do that on an 8-bit microcontroller.
  • System Modularity (Intents)
    • Intents embody the concept of inter-process communication and make it easy to modularize a system.  This architecture brings up a neat realization: once your app is using these to talk to itself, it’s a very small leap before apps start talking to each other.  This can be especially useful if you embrace the design philosophy that mobile apps should not have too many jobs, and that they should do 1-2 tasks efficiently.  Using an architecture based around Intents, complex tasks are now possible, while still holding true to the simplicity of each individual application.  This also provides great flexibility into way of hooking up with the core applications on the device (like mail and contacts) as just another module to your system.

I love my iPhone, and I love developing iPhone applications.  There are a lot of things on both the user and developer front that I prefer about Apple and the iPhone SDK.  I’ve chosen not to delve into them because so many people already have.  Any of the articles that I mentioned in the beginning spend a great deal of time touting the iPhone’s better features, so I’m just going to acknowledge (and agree) that they exist.  While these features alone may not skyrocket Google and cripple Apple, I believe that they are definitely enough to point out that Android has brought some new tricks to the party, and you probably ought to take notice.  I believe that they ARE enough to keep Apple from crippling Google straight out of the gate.

Android Layouts Supporting Orientation

It’s been my experience that most developers don’t want to deal with screen rotation in their applications. They will either specifically code the app not to respond to rotation events (which can look weird when you have to slide the screen and use the keyboard), or they will forget that there are instances where the screen orientation rotates for you by default (and their portrait-centric layout goes nuts or gets cut off). This is one of those subtle details that can drag down the user experience in a big way if the developer is not careful.

If your platform of choice is Android, my only question if you’re afraid of screen rotation would be…why?  Android makes dealing with different orientations in your views very simple.  If you’ve opted to define your layouts with XML (which you probably should anyway), then all that is required is a second XML file defining the second orientation (probably landscape), and some resource syntax to describe to Android how and when to choose the proper layout.  Defining layouts in XML is so simple, adding another doesn’t requre significant effort.  The general steps are as follows:

  1. Create two folders in the resource bundle (“res” folder in the project): “layout” and “layout-land”
    • “layout” will hold all the XML layouts for portrait mode
    • “layout-land” will hold all the XML layouts for landscape mode
  2. Create an XML layout in both folders with the SAME name (i.e. main.xml)
    • There will now be a “res/layout/<name>.xml” and a “res/layout-land/<name>.xml”
  3. Build each layout to match the proper screen orientation
  4. POOF! You’re done.  Android will handle the rest at runtime.

So what’s happening?  Well, “land” is an alternate resource that Android recognizes for screen orientation.  Creating the resource directory “layout-land” tells Android specifics about how the contents of the directory are to be used…specifically layouts for landscape.

Let’s look at a quick example:

Let’s say I have a layout with four image buttons.  In portrait mode, I want those buttons to block in a 2×2 arrangement.  However, in landscape mode, that block runs off the screen, so I want them all in a single row.  I will define two layouts:

res/layout/main.xml

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">
    	<TableRow>
			<ImageButton
				android:layout_width="wrap_content"
				android:layout_height="wrap_content"
				android:src="@drawable/image1"/>
			<ImageButton
				android:layout_width="wrap_content"
				android:layout_height="wrap_content"
				android:src="@drawable/image2"/>
	</TableRow>
	<TableRow>
		<ImageButton
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			android:src="@drawable/image3"/>
		<ImageButton
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			android:src="@drawable/image4"/>
	</TableRow>
</TableLayout> 

res/layout-land/main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="horizontal"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<ImageButton
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:src="@drawable/image1"/>
	<ImageButton
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:src="@drawable/image2"/>
	<ImageButton
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:src="@drawable/image3"/>
	<ImageButton
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:src="@drawable/image4"/>
</LinearLayout>   

Whenever the main.xml view is inflated, it will display either the TableLayout version or the LinearLayout version, depending on the screen orientation.