Sunday, October 5, 2008

Optimize your images

Java ME applications may use images in the PNG (Portable Network Graphics) format, version 1.0, but at least the critical chunks must be present. As ancillary chuncks are not necessary you may use a tool to remove them.
One such tool is PNGGauntlet. It is strongly recommended that you use it, as you may up to 60% compression of an image file.

Thursday, October 2, 2008

Showing a Splash

When customizing the User Interface with Canvas you can obtain the screen resolution with getWidth and getHight methods. Lets say you want to show a Splash screen to the user and have an image with your logo. How would you use it?
Well, a single image will not fit all screens. But two will do.
The smaller logo image should be less than 96x54, as this is the smallest screen resolution. This image can be used up to the resolution of 128x128 without problems. With bigger resolutions it will look tiny, though.
The bigger logo image should be a bit bigger than 128x128 and can be used up to 240x320.
The code bellow gives as example of how to implement this.

import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.Graphics;

class Splash extends javax.microedition.lcdui.Canvas {

  Image logo;

  Splash () {
    if (getWidth() <= 128) {
      // sl stands for Small Logo and does not need to have a file extension
      // this will use less space on the jar file
      logo = Image.createImage("/sl");
    } else {
      // bl stands for Big Logo
      logo = Image.createImage("/bl");
    }
  }

  protected void paint (Graphics g) {
    // With these anchors your logo image will be drawn on the center of the screen.
    g.drawImage(logo, getWidth()/2, getHeight()/2, Graphics.HCENTER | Graphics.VCENTER);
  }
}

Wednesday, October 1, 2008

Obfuscate your classes

An obfuscator can shrink and optimize your classes. Unused classes, fields, methods and attributes may be removed. The remaining code may be renamed to short meaningless names.
I use Proguard as an Ant task since 2003 and have good results with it.
Below are the settings I often use on my projects:
usemixedcaseclassnames="off", if class names reach z the next name will be aa instead of A.
defaultpackage="", all obfuscated classes are moved to the default package.
overloadaggressively="true", multiple fields and methods can get the same names, as long as their arguments and return types are different.
optimizationpasses="3", number of optimization passes to be performed. This may vary from one application to another. Check the final jar size, when it does not shrink any further, stop incresing this value.
printmapping="./mapping.txt", print the mapping from old names to new names for classes and class members that have been renamed. Useful when exceptions happen.
printusage="./deadcode.txt", list dead code of the input class files. Gives you tips of code that is not needed.
The only classes I keep are those that extends javax.microedition.midlet.MIDlet. So, for best jar size, my MIDlets are placed on default package. This way all classes are found at jar root.