Latest Tweets

 

Yoke Update

I’m currently in the closing months of an extremely involved enterprise e-commerce project that is occupying all of my time (pretty much), which is why I appear to have fallen off the Internet… but I am still here.

One concrete milestone I have reached in the last couple of months is to have version two of my Yoke server project published. Version one added support for users to share via Android applications. Version two has added preliminary support for developers to promote their Android applications.

Early support for App promotion

The first glimpse of this functionality peeking through into my own applications can be seen in this customizable app promotion widget that now accompanies all of my mobile apps:

It’s generated by application data stored by Yoke and inserted via a simple JS include onto any webpage. Without JavaScript, the widget safely fails-over to a link that takes the visitor to a simple webpage that contains the same information:

It’s a convenient way to ‘socialize’ my application download links and manage them from a single console, which currently looks a bit like this:

What’s next

I’m now slogging my way through an email pile-up and trying to carve out some time for my own development work prior to returning to it full time. So what do I have planned?

Mainly to start yoking all of my applications together. Progress on my mobile apps is well under way and I’m working on rolling Moseycode and Betan in too.

Sharing is hard to do (safely)

When I developed Daisy Garden for Android one of my goals was to build a simple environment in which people could share something, knowing that there was no possibility of being offended, or of giving offense. I certainly wanted an application where I never needed to be policeman to its users.

Imagining the phone in the hands of, say, a five-year-old child, it turns out that it is harder than one might expect to build something that permits safe and ready sharing; there are many constraints:

  • No user-supplied text — As soon as you allow users to type something - anything - and exhibit it to other users, there is the obvious potential for rudeness. I’m (broadly speaking) a libertarian so this doesn’t bother me much, but its obviously very easy for daft individuals to actively offend others in this way. Limiting the amount of text is useless, the Anglo Saxons bequeathed us a wonderfully rich collections of short curse words. Even with three characters, someone is going to try and produce an ASCII art penis, I just know it, because…

  • No user-supplied-imagery — …any environment where the public can upload photographs or pictures (even ones made from ASCII characters) will, eventually, contain pictures/representations of genitalia. I’m not sure why this is, perhaps sociologists can already explain the phenomenon, but it’s certainly lemmatical that…

  • Limited composition — …whatever medium you provide for visual expression, someone will use it to draw a penis. Even Nintendo were powerless contain this urge of humanity. Did they ever anticipate that inviting users to compete using their Mii designs would provide a worldwide forum for pornographic avatars?

Now, collaborative filtering can certainly address these issues, but only after a number of individuals have flagged the offending content. Returning to my example of the five-year-old holding a mobile phone, that child’s parent might not feel that a “flag as inappropriate” link was adequate in this context.

Back to Daisy Garden. In addition to these constraints, sharing necessitates that there is something worth sharing. Further to this, if you want people to share across cultural boundaries, it has to be something universal, something that everyone can appreciate. This is what led me to the idea of flowers, and gardens.

And I’m not as authoritarian within Daisy Garden as the observations above might suggest - where individuals share outside of the application, I’m much more relaxed - for example, users can name their flowers when they share them with others. But now that I’m beginning to add features that will allow users to share their garden designs with all other users of the application, I’m very glad I considered these things before I released the early versions of Daisy Garden.

P.S.

I did want to post/tweet this under the title “How to keep your application genital free”, but didn’t want to offend anyone.

Global Application State in Android

All applications carry some global state and Android applications are no different, but their componentized structure and the constraints of the hardware they are intended to run on throw up some new code design considerations.

Complex Android applications will have many possible entry points, for instance a user might activate the application from a launcher, or from a notification, or to fulfil a request by another application altogether, so you can’t make many assumptions about ‘where’ your application is going to launch from.

At the same time, the limited processing capacity available means that its important to avoid repeating work, so there are generally resources that you want to cache. But you will probably find that most of these resources will depend on a Context, so its not simply a case of hiding their acquisition behind static accessors as one might in a typical desktop Java application.

In addition, application management in Android puts a premium on rapid application start-up — users have every right to expect responsive applications — so in non-trivial applications it’s usually not the case that you can simply initialize all your global state because much of it may be wasted depending on how the application was launched.

My preferred approach is to sensibly modularize my global state and attach it to an Application instance that initializes it lazily behind static accessors. I’m not saying this is the only approach, or even the best, but it’s the one I use.

Since the Application component is always the first thing to be initialized in your application, you don’t need to worry about whether it’s ‘ready’ when you call it from other components (important caveat ContentProviders are started before the Application). Furthermore, if there is state you know you will always need when your application is launched, its onCreate() is an ideal place to do that work. Finally, and this is its most important benefit in my opinion, helper classes that need to hold-on to a Context to do their work, can do so permanently without inadvertently pinning an Activity or Service in memory. Of course, nothing stops you from being careful with the Context objects you choose to initialize your context dependent classes with, but this approach means you don’t need to be overly mindful of it.

import android.app.Application;
import android.content.Context;

public class MyApp extends Application {

    //sensible place to declare a log tag for the application
    public static final String LOG_TAG = "myapp";

    //instance 
    private static MyApp instance = null;

    //keep references to our global resources
    private static SomeResource someResource = null;
    private static AnotherResource anotherResource = null;

    /**
     * Convenient accessor, saves having to call and cast getApplicationContext() 
     */
    public static MyApp getInstance() {
        checkInstance();
        return instance;
    }

    /**
     * Accessor for some resource that depends on a context
     */
    public static SomeResource getSomeResource1() {
        if (someResource == null) {
            checkInstance();
            someResource = new SomeResource(instance);
        }
        return someResource;
    }

    /**
     * Accessor for another resource that depends on a context
     */
    public static AnotherResource getSomeResource2() {
        if (anotherResource == null) {
            checkInstance();
            anotherResource = new AnotherResource(instance);
        }
        return anotherResource;
    }

    private static void checkInstance() {
        if (instance == null)
            throw new IllegalStateException("Application not created yet!");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        //provide an instance for our static accessors
        instance = this;
    }

}

Daisy Garden, my latest Android application, in action. A poor quality video unfortunately - shot from my webcam. It doesn’t include sharing flowers yet, but it will.