Programming for Android

January 15th, 2010 No comments

So I’ve done my first programming for Android phones and thought I’d write a blog post about the experience.

Programming for Android is a bit different from working with the Compact Framework. The abstraction level for the Dalvik applications is somehow high than the Compact Framework application. One difference for example is that there is no main() method to start your application from.

Central for an Android application is its Android Manifest file. This file describes all services and activities available in the application. This is an XML file that helps describe your application to Android, what it’s capabilities are. Each Activity can then be used as an Entry point, but the manifest also describes Services, Content Providers and Broadcast receivers.

What this gives you is a set of loosely coupled components that interact with each other using Intents, that are passed on a system wide message bus. This allows applications interact not only with central parts of the phone, but also with other applications. Which is quite interesting.

Developing in this manner gives you a set of conventions to follow. I feel that they have managed to find a set of conventions that gives direction in the design of the application, but doesn’t confine you.

The SDK also gives you a set of base classes (template method pattern style base classes) that helps you develop common tasks in a standardized way. An example of these are the Task classes that provide threading and scheduling support. I quickly fell in love the the AsyncTask for example.

Android protects the foreground UI thread quite extensively, making these constructs for doing background work important. For example your not allowed to construct or access any UI elements on background threads. This can be handled by using a special Looper construct that effectively divides your Thread code into different parts. One setup part that’s allowed to access, or setup UI components. And one Loop part that does the actual work.

I worked mainly in the Emulator. The emulator feels fast at first, it takes a while to boot up but is quite responsive once booted. That is until you start typing using the computers keyboard. When you do this the emulator feels slow. Apart from a few issues with the emulator loosing “internet connectivity” when my computer Hibernated.

Now it’s time to mention a tool that’s quite helpful when working with Android applications. It’s the adb.exe logcat tool available in the Android SDK. This tool allows you to watch the result of log statements in runtime, and shows stack traces for those errors the occur but you’ve partially managed to take care of (ignored).

This being said there are some things I’m missing when comparing to working with the Compact Framework. For example, working with XML is much easier in the Compact Framework. I hate having to write my own parsing and serialization code, and there are more tools to help me generate code for doing this in the .Net framework.

Also using the HttpClient in the Android SDK is unnecessarily hard. Https works only with some special glue code. And as far as I can tell everyone seems to simply accept any certificate instead of providing support for showing a UI where the user can accept an unknown (self-signed) certificate.

This is all I can think of right now (this is the second time of writing since I had a crash when I tried to post it…). If there are any questions, please ask them. Hopefully they’ll help generate more knowledge about Android development.

Bookmark and Share

Inheritance of features

January 14th, 2010 2 comments

Given my recent combining of Tracks and Shuffle. An interesting thing happened. Something that happens when you combine two products so that they inherit features from each other.

On Shuffle’s issue list there are a few items currently regarding repeating tasks, and the ability to hide a task for a period of time. Tracks has these features, since Shuffle can synchronize with Tracks, Shuffle now also have these features. That is if you choose to synchronize with Tracks.

I’ve done a few integration projects thus far. And the ones that are truly successful are when they take the aspects and features of both applications into consideration, to create a win-win scenario between the two applications.

Here is another recent example. At RemoteX, we recently integrated a system that handles the ordering of materials, goods, equipment etc. In essence this integration feature means that you can go to a retailer, order goods, specify the order they should tag the invoice with. End result, RemoteX automatically adds the goods to the application and if possible attaches a copy of the invoice to the case. Ready to be billed to the customer. Since the other system has integrated with almost all resellers of service equipment in Sweden, the daring customers running this set-up can, at least in theory, eliminates the need for keeping stocks of equipment or goods in house.

If you understand where these synergy effects can show up you can also align the integration so that both applications maximizes the gain of integrating with the other system. This is important to think of when designing an integration, how do we achieve the maximum win-win?

Bookmark and Share

The guessing user interface

January 13th, 2010 No comments

My girlfriend has downloaded a solitaire application to her HTC Tattoo. While solitaire isn’t anything revolutionary it has an interface feature which got me thinking.

Se what the interface does is move those cards that it is sure that the next step is to move. So if I for example get an Ace, it moves it to it’s correct place at the top four card stacks.

This feature got me thinking about mobile phone interfaces. In applications in general, but even more so in the mobile context, you want to reduce the amount of interaction done with the user interface.

What if we can “guess” the input of the users input in the interface even in business applications?

image

We have hints in the domain, such as if you select this type of project you cannot register this type of time on it. You don’t register vacation time on a customer’s bill if your a consultant. Well, at least not that often.

These hints are common constraints, you might not want to enforce them by disabling the alternatives available. But you can check them and see if for a given input if there are any “assumptions” you can make about the next input to be made.

image

To take this one level further. We have the application data. We can order things in the UI according to a statistical analysis. Given this value in a combo box, this other value has more than 80% chance to be set in the other combo box. In such a case we can “guess” that this is the input the user would want to enter, and worst case is that he has to change it.

The cost of changing a value in a combo box is equal to setting one in the first place.

Now statistical analysis of data can often be costly, and typically not something you would want to do in a UI scenario. But what you can do instead is to calculate the statistical values into a decision graph (I think of it as similar to a Markov process for those whom have studied them). We can calculate this graph every evening and have a graph available for all input for the next day. Traversing the graph is now a simple algorithmic exercise.

Bookmark and Share
Tags: , ,

Shuffle 1.4.0 available on Android Market

January 12th, 2010 2 comments

Regarding the previous post, Shuffle 1.4.0 with Tracks synchronization is now available on the Android Market.

Bookmark and Share
Tags: ,

Testing without mocking framework

January 12th, 2010 4 comments

I had it pointed out to me at the end of last year that I use Mocks too much. I isolate the class under test more than I might need to do. Isolation of a class has the most value at service boundaries. If other classes can safely be included in the test without side-effects, I’m actually testing more than jus the class under test.

This is a bad thing, right? No. Not necessarily. The tests purpose is to prove that the code solves it’s intended purpose. If by including more of the system that this piece of code interacts with, the test will be more tightly coupled to the actual use of the class.

If I isolate the class, non-API breaking changes in other classes might cause the requested system behavior to fail, but my test which tests the class in isolation will still pass. The purpose of my tests should naturally be to detect defects earlier.

As I considered this I went back to the places in our code-base where I feel TDD has really really helped me. And sure enough, almost no mocking in those tests, relying instead on actual objects. For me, this was sort of an eye opener.

How do I work without mock’s then?

One example is to use inheritance. If I isolate all calls to system-boundaries to a single method, I can inherit from the class under test and override that system-boundary specific piece of code. This allows me create “mocked” version of the class without the need for mocking libraries.

This is called Test-specific subclass. Thank you Patrik!

This method is even applicable to legacy code where mocking isn’t applicable.

Another example would be to use actual objects all the way, if possible. For databases for example you could create a temporary testing database if you have access to a database server. Depending how you access your data you might even be able to have an in memory database instead of an actual database. While this might mean you need to implement a test-class instead of mocking it. If the API doesn’t change all to often it might save you time compared to mocking.

http://xunitpatterns.com/Test-Specific%20Subclass.html
Bookmark and Share
Tags:

Shuffle and Tracks

January 11th, 2010 No comments

As I mentioned in a previous post I’ve been working on getting the Android application, Shuffle to synchronize with Tracks.

Now that the work has continued this post describes how this feature of Shuffle works. This feature is released with version 1.4.0 of Shuffle and will be available on the Android Market. Special thanks to Andy whom put up with my loads patches.

This feature affects no other features in Shuffle, it simply allows the synchronization between the two systems. If you never configure the synchronization feature it will never affect you.

Configuration

To configure Shuffle to synchronize with tracks start the Shuffle application.

image imageimage

Press menu, and select settings. Select the option called “Change synchronization”

image image

This will open the settings file. Here you can enter the URL to your Tracks installation, username and password. You can also specify the settings for the background synchronization. Simply change the combo box between the different settings.

There is some validation in the settings screen. If you enter a invalid URL the text will change to red to display this.

image image

When you save your settings they are validated by trying to download the contexts from Tracks. If Shuffle cannot get any content from Track with the specified settings it will not save them, but instead display an error message saying that something is wrong with them. You can always cancel.

The Synchronization

Once Shuffle is configured to synchronize with Tracks. You will have an extra button available in the menus across Shuffle. Pressing this will start the synchronization process. To notify that a synchronization is in progress Shuffle will also add a notification message during the synchronization. This is to notify the user that Shuffle synchronizes when doing background synchronization. If you click the notification Shuffle will display the synchronization view.

image image image

The synchronization synchronizes the entities in Shuffle in the following order: Contexts, Projects, and Tasks. During a synchronization Shuffle will look at the modification date and select the version of the entity that was latest modified, and merge this entity with the local entity or remote entity, which ever is updated.

image

Tracks only accept Tasks that have a context set, currently these tasks are excluded from the synchronization process. If you have such task a message is displayed at the end of the synchronization process.

Bookmark and Share
Tags: , ,

Synchronizing Tracks and Shuffle

January 4th, 2010 6 comments

I did some open-source work last week. I created a synchronization option in the Android program called Shuffle. Allowing it to synchronize with the web tool called Tracks.

Here is a description of how to use the synchronization in Shuffle.

Configuration

image

image image

Open the settings menu, select the Change Synchronization option.

Specify your Tracks installation URL, username and password.

Make sure that the URL is correctly formatted and that there is no ending slash in the url:

this is wrong: http://my.gtdify.com/

this is correct: http://my.gtdify.com

Usage

image image

On the menu available in most screens there is a button called synchronize. Click it and the synchronization starts. It will first synchronize the contexts, then project and last the Tasks.

Details of the synchronization

The synchronization will try to reduce duplicates that might occur between Tracks and Shuffle. This is done by looking that the description of tasks and the names of contexts and projects.

The synchronization works with a server wins, modification date oriented approach. Should there be a conflict the latest version will win, and in it will try to take as much detail it can from Tracks.

Also, using the “Delete completed” option removes the tasks from Shuffle. This means that the synchronizer wont find them and can’t mark them as finished in Tracks. If you use this synchronization I recommend letting the synchronizer take care of the “cleaning up”. This will be done the second synchronization that a task is complete on.

That is, if you complete a task and synchronize, both tasks will be in both systems as completed. Synchronize again the the task will be removed from Shuffle,  but maintained as completed in Tracks.

Bookmark and Share
Tags: , ,

Happy new year!

December 31st, 2009 No comments

Happy new year everyone!

To celebrate I’m posting this screenshot.

image

I’ve been using Shuffle on my HTC Hero for a while now, and been lacking the ability to synchronize it with a online desktop-enables solution.

Well, the above screenshot is the result of what I’ve been doing these last two days. It’s Shuffle that’s synchronized its contexts with a Tracks installation. Still a lot to do, probably a day or three at least. But it’s looking promising.

Happy new year!

Bookmark and Share
Tags: ,

Ops…

December 18th, 2009 No comments

I found this just now, in some formatting code:

if ((data.TotalPrice - data.TotalCost) < 0)
 {
 ApplyToCells(row, cell => cell.Style.ForeColor = Color.Red);
 }
 ApplyToCells(row, cell => cell.Style.ForeColor = Color.Black);

Problem is that it should have been

 if ((data.TotalPrice - data.TotalCost) < 0)
 {
 ApplyToCells(row, cell => cell.Style.ForeColor = Color.Red);
 }
 else
 {
 ApplyToCells( row, cell => cell.Style.ForeColor = Color.Black );
 }

This caused an infinate repainting loop, oh well. fixed now. Trouble is that no one tested the scenario when the row had negative.

Bookmark and Share
Tags:

AppEngine + Grails + Cron

December 16th, 2009 5 comments

I just added a Cron job to “ping” my application every 1 minute. After a short discussion with Paul Cusch, whom commented on one of my previous posts regarding the load request issues Grails on AppEngine is seeing. I decided to give it a try. This solution is entirely based on Paul’s idea I’m just writing it up.

Grails AppEngine plugin is missing a feature to use cron out of the box. I hope to submit a patch for it. This is how it works. You need to have a cron.xml file next to your appengine-web.xml file. In the cron file you describe which url and how often a GET operation should be done on the specified url.

Details can be found here.

I simply added a request to a specified url, which I added to my URL mapping:

"/today"(controller: "user", action = "ping")

Then added a cron file to ping it every minute:

<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
    <cron>
        <url>/today</url>
        <description>Keep the app alive by ping every 1 minutes</description>
        <schedule>every 1 minutes</schedule>
    </cron>
</cronentries>

The cron.xml file I keep in my grails-app/conf directory, following the conventions used by the AppEngine plugin, for similar files.

The user controller unfortunately got the honor for hosting the ping request.

def ping = {
  render "ping ${new Date().toString()}"
}

And there it is. Next time that application is uploaded to the AppEngine, the ping method on the user controller will be executed every 1 minute. Helping to keep the application loaded.

This method comes with a few drawbacks however. The application will still hit loading requests every now and then, and those requests will take from your quota. This setup can easily eat up all your free quota.

Also, if everyone sets up this cron job. Then a lot of quota is wasted in general, which might affect the service for other applications. This workaround tries to fix a problem that should be fixed in the inner workings of AppEngine it self (not excluding changes to Grails initialization).

There is however a query that is ongoing. Google is considering the possibility to allow people to pay for keeping their application in memory. If you would consider such an option then star the this issue. I myself starred it, I think it’s quite acceptable.

I turned the cron loading task off in my application, instead seeing it as an experiment with Cron on Google AppEngine. The payoff for this solution wasn’t that great and for me it comes with the expense of some of my code quality.

Bookmark and Share