Showing posts with label small. Show all posts
Showing posts with label small. Show all posts

Tuesday, July 19, 2011

Don't use RecordComparator

Even if you try to keep the number of classes to a minimum you must create some classes to represent your entities. More so if you use these entities on IO operations: save on recordStore; send on httpRequest; etc.



This tip is for those who do not use/know Floggy and create methods to [de]serialize these entity classes from/to byte arrays:
Do not use RecordComparator



Why? Because this interface defines a compare method that receives two byte arrays, you should know how your entities are represented as byte arrays and compare them only with array indexing. If you deserialize a class only to compare it you will be wasting a load of memory only to sort your RecordEnumeration.



I consider a better approach to load your RecordStore without a RecordComparator, deserialize your class and use an insertion sort algorithm on a Vector.



Related topics:

Monday, October 12, 2009

Alphabet: my third study case

With this application you can help your children learn the alphabet. Three letters at a time. When the child correctly presses the key for each letter three other letters are presented. There is a counter to stimulate the child to achieve higher scores. You can change letter colors based on the handset theme, but the application also have predefined colors.


The application is available for downloa here.


Related topics:


Wednesday, September 2, 2009

Books: a new study case

Updated on 31/May/2010. New features on version 1.4

I had some TXT books and wanted to read them on my cell phone.
So I made this application and shared it.

Features:


  • Fullscreen landscape reading with biggest font available.

  • Recent files list, so you do not need to browse for files every time you open the application.

  • Resume reading from the same line you were (with progress bar since version 1.1) - no key pressing just to find the point you were before.

  • Press and hold to fast forward or rewind with increasing speed (since 1.1).

  • Languages: English, Español, Français, Português (since 1.2).

  • Read UTF-8 encoded files (since 1.3).

  • Color verification to guarantee scroll bar is always visible (since 1.3).

  • Presenting error dialog when an unexpected situation occurs (since 1.3).

  • Checking file size before trying to open it (since 1.4).

  • Line number presented on footer during read (since 1.4).

  • Better touch support: go to previous pages (since 1.4).



You can open files using JSR 75 - FileConnection.
When you enter "Open File" screen your cell phone might ask you to grant read access to the application.
With Sony Ericsson I had to grant it only once, at the first execution.
With Nokia it was necessary to grant every folder the application was trying to read.
If some unexpected situation occurs an error dialog will be presented with details.
You can send me these details by email.

The content is shown in landscape/fullscreen mode thanks to Sprite transforms, so MIDP 2 is required.

To use the maximum available space just for text I did not set title nor Commands on main Canvas and treated keyPressed to identify softkeys.

Each file read is kept on a "Recents" screen.
A List where the top most items are the most recent files opened by the application.
I used a simple RecordStore to keep this list of files and where in each file we were reading.

Give it a try and, if you like it, write a nice review. ;)

Related topics:

Wednesday, December 10, 2008

Chess: A study case

Since June/2007 I have been studying how to develop small and adaptive Java ME applications. My study case is a simple chess board and is available for free at GetJar.
Current version has help text, good usability, unselect feature and support for touch screen devices. But still does not support check mate.
I have just uploaded a new version. A single 15k jar file that supports resolutions from 128x96 up to 240x320 and higher.
Feel free to give it a try, leave a comment or better: write a review.

Sunday, November 2, 2008

Remove debug messages

While developing an application it is common place to first use emulators. This environment gives access to stepping and watching variable values. Very useful, high development speed.
Then you need to run the application on actual devices. Some manufacturers implement On Device Debugging so, the same environment is available even when the MIDlet is running on an actual device.
For those that do not have ODD it is necessary to use some sort of logging mechanism, but all need the developer to add debugging code. Code that is not part of the application, that need to be removed before the final build, that is just wasting valuable space.
How can we be sure there is no debugging code?
One common practice is to define a public boolean constant that toggles debugging off:

public static final boolean DEBUG = true;

Every line of debugging code should be enclosed within an if block:

if (DEBUG) {
    // debug code
}

If you set the constant to false the Java compiler will not add the if block to the class file.

Friday, October 17, 2008

The smallest MIDlet

A Java ME application must have at least on class that extends MIDlet. If the application has custom interface there must be at least one class that extends Canvas. In this case, how short can be the MIDlet?

import javax.microedition.lcdui.Display;
import javax.microedition.midlet.MIDlet;

public class C extends MIDlet {

  MyCanvas cCanvas;

  public C() {
    this.cCanvas = new MyCanvas(this);
  }

  protected void startApp() {
    if (Display.getDisplay(this).getCurrent() == null) {
      Display.getDisplay(this).setCurrent(this.cCanvas);
    }
  }

  protected void pauseApp() { }

  protected void destroyApp(boolean arg0) { }
}

We use the default package because packages are directories inside the jar file and we want to keep the jar flat.
The class name is just one letter because the obfuscator is configured to not change the name of classes that extends MIDlet. So, we take the smallest name possible.
The only attribute is of the type of the class that extends Canvas. The instance is created at MIDlet constructor because initialization during declaration creates bigger class files.
At startApp we avoid the use of a local variable of type Display, this also reduces the final class size.
We removed the throws clause of startApp and destroyApp because the import entry of MIDletStateChangeException is not needed, reducing the class size.
MyCanvas class receives the MIDlet as parameter at constructor to call notifyDestroyed when the user selects an Exit command. This is the only class that implements CommandListener.
With this minimum MIDlet all application logic is kept inside MyCanvas.

Wednesday, October 8, 2008

Fewer classes

Each class definition creates a corresponding class file, even nested classes. The fewer classes you have the smaller your jar file will be. A Java ME application may have only one class, the MIDlet, and this single class can implement CommandListener and be responsible for all application GUI.
If you are developing a game or an application with custom user interface, you will need another class that extends Canvas, but this is the bare minimum.
Having all your application code in one or two classes is not Object Oriented programming. It is not easy to develop like this if you use a simple text editor, but it can be done with current IDEs like Eclipse or NetBeans.
Keep in mind that, for achieving small jar files, you will need to use development techniques not related to OO.

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.

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.

Monday, September 29, 2008

Keep it flat

Jar files are Zip files with another extension and a special (and optional) folder named META-INF. For each file or folder there is a header associated. As headers take some space of the jar you better keep less files in it, but if you already took it to the bare minimum then keep all those files in the root directory.
For MIDlet distribution the jar file must have the META-INF folder so, for best space usage, your jar files should have only this folder. Your MIDlet and all other classes should be on default package. The same with resource files, keep all of them at file root.