Dynamic Class Loading

If you wish to make use of a functionality which is not supported on all target platforms and not vital to your application, you can use dynamic class loading to make the same binary application package run on all targets and revert gracefully if the additional functionality is not available on the current platform. For example, you may wish to create a game which runs in a standard canvas on MIDP 1.0 and in a full screen canvas on MIDP 2.0.

Why would that be a problem?

In order to use a full screen canvas on MIDP 2.0, you will need to use the MIDP 2.0 method Canvas.setFullScreenMode somewhere in your code. The class which makes this call needs to be compiled against MIDP 2.0. If your application directly references this class, it will not be able to run on MIDP 1.0.

What is the solution?

Create an interface Compatibility.java defining methods which are platform dependent, in this case setFullScreenMode(Canvas C). We can then create an MIDP 2.0 class Compatibility20.java which implements this interface method by calling C.setFullScreenMode(true). This class must be compiled against MIDP 2.0 and packaged with the application. At run-time, the application must check whether it is running on MIDP 2.0. If yes, it may dynamically load the class Compatibility20, cast it to Compatibility and call the method setFullScreenMode on it.

How do I check the platform at run-time?

To distinguish between MIDP versions, you can use System.getProperty("microedition.profiles"), which should return a string similar to "MIDP-2.0". For more specific information, you can query System.getProperty("microedition.platform"). The format of this string is not standardized, e.g., my Nokia 7250i simply returns "Nokia7250i". If the string starts with Nokia, it most likely really is a Nokia device. On the other hand, if your application encounters a Nokia model where the result does not start with Nokia, the worst thing which could happen is that the application treats it as a plain MIDP 1.0 device and does not use extra functionality.

How do I load a class at run-time?

Compatibility c = (Compatibility) Class.forName("Compatibility20").newInstance();

Of course, you should use a try-catch block in case something goes wrong. In fact, it would probably be possible to check the platform simply by attempting to load all supported compatibility classes until you find one which does not generate an error, but some devices might choke on that.

Hello world!

The above example works, but is somewhat simplified. Suppose you would like to use full screen mode also on Nokia phones (via the Nokia UI API). Instead of changing the state of the Canvas, this requires to use the class FullCanvas. So, the compatibility method would actually have to create and return a new Canvas object. Furthermore, the GUI classes in your application may not derive from Canvas, because the actually used type is not known at compile time. Instead, they will need to host a Canvas instance.

This is still not good enough, because you no longer receive notifications such as paint and keyPress if you do not derive from Canvas. Therefore, the real solution requires to implement a CanvasWrapper class which reroutes such events using a listener. The compatibility method for Nokia then actually returns an instance of CanvasWrapper20, which in turn derives from FullCanvas.

Back to MIDP page

0 comment(s) have been added to this topic:

Note: Adding comments has been disabled for the time being, as too many bots left their spam and I didn't feel it worthwhile to add a humanity check. Just send me a mail if you wish to contact me.
Copyright (C) 2006-2013 by Christian Fröschlin. Please note the legal disclaimer. If you experience problems with this page, contact webmaster@chrfr.de.