ExecutableTask pattern to tackle J2ME multithreading

Programming on the mobile device is quite different to more common environments like web or client-server desktop applications. Although mobile devices become always more and more powerful (i.e. like iPhone's OS and Android) one has still to consider issues like limited memory and I/O devices. Take for instance a look at the Android best practices.

When programming on J2ME for the CLDC these kind of things are key issues that have to be considered. There are a number of best practices around, one being the advise to place "heavy" computations in a separate thread in order to not block the J2ME system thread. That implies that you'll have to deal with a lot of threads that need to be handled. Keeping track of the execution of these threads can often become quite complicated.
Therefore - in my last J2ME project - I've created what I called the "Executable Task pattern" in order to handle these situations more easily. Actually it's not a pattern per sé but more like a variant of an Observer and Command pattern. A similar approach is used for defining the Java Swing event handlers for button clicks etc.

The "Executable Task" is composed of two objects.

public abstract class TaskProcessListener {
 /**
  * Gets invoked when the {@link ExecutableTask} finishes processing
  * @param result the resulting object from the computation
  */
 public abstract void onSuccess(Object result);
 
 /**
  * Gets invoked when an error occurs during processing
  * @param status the status message containing information about the error
  */
 public abstract void onError(String status);
}

This is the abstract class that defines the abstract methods that have to be implemented. This "TaskProcessListener" is used by the 2nd class, the "ExecutableTask".
public abstract class ExecutableTask implements Runnable {
 protected TaskProcessListener listener;
 
 public ExecutableTask(){ 
 }
 
 public void run(){
  //initializations prior the execution of the task itself
 }
 
 public ExecutableTask(TaskProcessListener listener){ 
  this.listener = listener;
 }

 protected void notifyTaskFinished(Object result){
  this.listener.onSuccess(result);
 }
 
 protected void notifyError(String statusMessage){
  this.listener.onError(statusMessage);
 }

 public TaskProcessListener getListener() {
  return listener;
 }

 public void setListener(TaskProcessListener listener) {
  this.listener = listener;
 }
}

This is the main class, but still quite simple, isn't it? There isn't much to explain here, just a couple of class members and getters and setters. Note however that the class is declared abstract and that it inherits from "Runnable", meaning that it can be executed within a thread.
Now comes the interesting part. When you actually have an operation that needs to run within his own thread (i.e. a network access) you inherit from the ExecutableTask class instead of Runnable as you would usually do. Consider for instance the simple code for downloading an Image from the web by using an HttpConnection which I've posted a couple of days ago. You would code that as follows:
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import javax.microedition.lcdui.Image;

public class ImageLoaderTask extends ExecutableTask {
 private String imageUrl;
 
 public ImageLoaderTask(String imageUrl){
  this.imageUrl = imageUrl;
 }

 public void run() {
  HttpConnection connection;
  try {
   connection = (HttpConnection) Connector.open(this.imageUrl);
   connection.setRequestMethod(HttpConnection.GET);
   
   Image loadedImg = Image.createImage(connection.openInputStream());
   notifyTaskFinished(loadedImg);
  } catch (Exception e) {
   notifyError(e.getMessage());
  }
 }
 
}

The instantiation of the ImageLoaderTask is then done by writing...
ImageLoaderTask imageLoadTask = new ImageLoaderTask(imageUrlField.getString());
imageLoadTask.setListener(new TaskProcessListener(){

 public void onError(String status) {
  //alert the user about the problem
 }

 public void onSuccess(Object result) {
  //do something with the result
 }
 
});
...again really simple. You can use the "onError(...)" for notifying the user about some problem during the execution of the task and the "onSuccess(...)" for processing a successful outcome.
The following Form demonstrates the usage of the ImageLoaderTask:
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.TextField;
import javax.microedition.lcdui.Ticker;

public class ImageForm extends Form implements CommandListener {
 private TextField imageUrlField;
 private Command loadImage;
 private Display display;

 public ImageForm(Display display) {
  super("Image Viewer");
  init();
  this.display = display;
 }

 private void init() {
  imageUrlField = new TextField("Image URL", "", 999, TextField.URL);
  this.append(imageUrlField);

  loadImage = new Command("Load Image", Command.SCREEN, 1);
  this.addCommand(loadImage);

  this.setCommandListener(this);
 }

 public void showLoadedImage(Image image) {
  if(this.size() == 2)
   this.delete(1);
  this.imageUrlField.setString("");
  this.append(image);
  this.setTicker(null);
 }

 public void commandAction(Command c, Displayable d) {
  if (c == loadImage) {
   downloadImage();
  }
 }
 
 private void showMessage(String message){
  this.setTicker(new Ticker(message));
 }
 
 private void stopMessage(){
  this.setTicker(null);
 }
 
 private void downloadImage(){
  showMessage("loading image");
  
  ImageLoaderTask imageLoadTask = new ImageLoaderTask(imageUrlField.getString());
  imageLoadTask.setListener(new TaskProcessListener(){
  
   public void onError(String status) {
    stopMessage();
    
    //show an alert notifying about the problem
    Alert alert = new Alert("Error", "Error when loading image " + status, null, AlertType.ERROR);
    alert.setTimeout(Alert.FOREVER);
    display.setCurrent(alert);
   }
  
   public void onSuccess(Object result) {
    showLoadedImage((Image)result);
   }
   
  });
  
  Thread t = new Thread(imageLoadTask);
  t.start();
 }

}

What is a browser?

Do you know the answer? I'm pretty sure (> 90% of the blog readers here have a technical background). But check out this video to get a feeling of how non-technical users view the world of browsers, search engines and the Internet.

This survey has been conducted by Google and just about 8% knew the correct answer. The other 92% have no clue of what is IE, FF or Chrome. They even mix up things like search engines and browsers. This demonstrates how difficult it is to gain market share on browser applications and is probably also one of the reasons why Internet Explorer is still the most-used browser (by non-tech people): Just because Windows is the most widely distributed Operating System and it ships Internet Explorer. For non-tech users "Internet Explorer" is "the Internet". That's why sentences like "Can someone help me, I deleted the Internet" come up :)

Firefox 3.5

Here's a short video of the director of the Firefox development team showing the new features in version 3.5 which should be available soon (these days actually).

MIDlet for downloading image from the web

J2ME provides several ways for creating an Image object:

  • Image.createImage(String)
  • Image.createImage(byte[], int, int)
  • Image.createImage(InputStream)
 If you want to download an image from the web to your local J2ME application, you - of course - have to establish an HttpConnection and retrieve the image with a simple GET.
As I noticed, most programmers then open the InputStream by calling httpConn.openInputStream() and process it inside a while loop, storing the read bytes in a ByteArrayOutputStream or similar for then being able to create the image, using the 2nd method illustrated at the beginning. This approach is shown here for instance.
But knowing the 3rd method for loading an image directly from an InputStream, this could be achieved in a much easier way:
public void run() {
 HttpConnection connection;
 try {
  connection = (HttpConnection) Connector.open(this.imageUrl);
  connection.setRequestMethod(HttpConnection.GET);
   
  Image img = Image.createImage(connection.openInputStream());

  //do something with the image
 } catch (IOException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }
}
Note, the operation of establishing an HttpConnection, fetching the image etc is done within a separate thread (see best practices). Of course the code above needs some tuning, this is just a simple example to demonstrate the topic.

Here's a MIDlet which follows this approach:
package com.tests.images;

import java.io.IOException;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.TextField;
import javax.microedition.lcdui.Ticker;

public class ImageForm extends Form implements CommandListener {
 private TextField imageUrlField;
 private Command loadImage;

 public ImageForm() {
  super("Image Viewer");
  init();
 }

 private void init() {
  imageUrlField = new TextField("Image URL", "", 999, TextField.URL);
  this.append(imageUrlField);

  loadImage = new Command("Load Image", Command.SCREEN, 1);
  this.addCommand(loadImage);

  this.setCommandListener(this);
 }

 public void showLoadedImage(Image image) {
  if(this.size() == 2)
   this.delete(1);
  this.imageUrlField.setString("");
  this.append(image);
  this.setTicker(null);
 }

 public void commandAction(Command c, Displayable d) {
  if (c == loadImage) {
   this.setTicker(new Ticker("loading image"));
   
   ImageLoaderManager imgMan = new ImageLoaderManager(imageUrlField.getString(), this);
   Thread t = new Thread(imgMan);
   t.start();
  }
 }

}

class ImageLoaderManager implements Runnable {
 private String imageUrl;
 private ImageForm parent;

 ImageLoaderManager(String imageUrl, ImageForm parent) {
  this.imageUrl = imageUrl;
  this.parent = parent;
 }

 public void run() {
  HttpConnection connection;
  try {
   connection = (HttpConnection) Connector.open(this.imageUrl);
   connection.setRequestMethod(HttpConnection.GET);
   
   parent.showLoadedImage(Image.createImage(connection.openInputStream()));
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
}

iGoogle Gadget: Stackoverflow Profile View

Are you a member of Stackoverflow.com and you want to track your profile such as your reputation or earned badges? A couple of days ago I've submitted an iGoogle gadget that makes this easy. Here's a screenshot and some further links.

Add to Google
Gadget project site
Official iGoogle directory entry