In the section Acquiring and Installing J2ME Development Kit above, you downloaded the Toolkit and installed it in the folder C:\WTK22 (as far as this article series is concerned; you may have downloaded and installed it in a different folder). Let's explore the contents of this folder. Figure 4 shows these contents as they should now look on your machine.
Figure 4. Wireless Toolkit folder contents
Note that the default installation of the Toolkit would not have created the article folder, and that you created it in the previous section.
As far as a MIDlet developer is concerned, the most important folders are the apps and bin folders, but here is a short summary of each of these folders.
Folder Name
Folder Description
Figure 4. Wireless Toolkit folder contents
Note that the default installation of the Toolkit would not have created the article folder, and that you created it in the previous section.
As far as a MIDlet developer is concerned, the most important folders are the apps and bin folders, but here is a short summary of each of these folders.
Folder Name
Folder Description
appdb
Directory that acts as a simulation for mobile device file system
apps
MIDlets created using the Toolkit reside in this directory
bin
Contains executables for the various tools, including the Toolkit itself, and various other tools like the preverifier and the emulator
docs
The Wireless Toolkit documentation including API documentation for MIDP 2.0 and MIDP 1.1
lib
Contains the JAR files for MIDP (both 2.0 and 1.1), CLDC (both 1.1 and 1.0) and several other optional libraries
sessions
Directory where network and profiling sessions are maintained
wtklib
Contains the libraries for the Toolkit itself, including the properties of various device emulators
The apps folder is the directory where all the MIDlets that are created using the Toolkit are installed. Browse this folder, and you will notice several example MIDlets provided in their own folders. These have their own directory structure that allows clean separation of source code, libraries, and rest of the files associated with a MIDlet project.
The bin folder contains the executables for the Toolkit. The most important one is ktoolbar.exe (on Windows), which starts the main interface window for the Toolkit. This folder contains other executables as well, some of which we came across earlier (for example, preverify.exe and emulator.exe). Let us, however, concentrate on using the Toolkit now by running the ktoolbar.exe from the bin folder. The Toolkit will start and you will get the window shown in Figure 5.
Figure 5. Main Toolkit window
As the message in the window says, from here, you can either create a new project or open an existing one. When you click on the Open Project menu button, you will be presented with a list of projects. As you may have guessed, this list of projects is the directory listing of the apps folder. Selecting a project from this list will open up the project and allow you to change its settings, build it (which includes compilation, preverification, and packaging) and run it. The steps of designing and coding are still to be done outside of this Toolkit.
Let's use the Toolkit to create the Date-Time MIDlet from the previous section. Click on New Project menu button, and enter the details in the window that comes up, as shown in Figure 6.
Figure 6. Creating a new project
The next window that comes up will allow you to change settings that control the target platform of your MIDlet. In this case, you want to target this MIDlet towards the MIDP 2.0 and CLDC 1.1 platforms and therefore, keep the Target Platform as JTWI, which preselects the MIDP 2.0 Profile. However, you will need to change the Configuration to CLDC 1.1 and uncheck the Optional Mobile Media API library, as shown in Figure 7.
Figure 7. Changing project settings
You can review the rest of the settings by clicking on the tabs at the top, but for the moment, your project is ready to be created. Do so by clicking the OK button at the bottom. The project will be created with information about where to place the project files displayed on the screen, as shown in Figure 8. You can verify that the Toolkit has created a DateTimeApp folder under the apps folder by navigating to it.
Figure 8. Project DateTimeApp created
You have already created the only required src file for this MIDlet in the previous section. Copy this file, DateTimeApp.java, from the folder C:\WTK22\article\com\j2me\part1\ to the fully qualified src folder (C:\WTK22\apps\DateTimeApp\src\com\j2me\part1). Note that the Toolkit created the fully qualified path based on the package name, so you don't have to. Once the copy is done, come back to the Toolkit, and hit the Run menu button. The Toolkit will compile, preverify, and package, and, provided everything goes OK, will run the DateTimeApp in the emulator. Seems simple enough, doesn't it? All you had to do was to create a new project, set the settings, write the code, drop it in the right directory, and hit the Run button. The Toolkit took care of the rest.
Before you leave this section, examine the rest of the folders under the DateTimeApp project. The bin folder under the DateTimeApp folder contains the JAD and the Manifest files, while the classes folder contains compiled classes. But where is the JAR file for this MIDlet? Well, the JAR file is not created by just running (or building) your application in the Toolkit. To create the JAR file, you will need to select the Project menu item, and then select one of the options under the Package submenu, as shown in Figure 9.
Figure 9. Creating the MIDlet's JAR file
By creating this package, the JAR file will be created, with correct Manifest information in the JAD file. You can even create the HTML file that we created in the deploy section previously, by clicking on the Run via OTA (Over The Air) menu. This will not only allow you to simulate your emulator running this MIDlet via the Internet, but also create the HTML file for you in the bin folder. Before you can use this HTML file to deploy on your own server, along with the JAD and the JAR files, you will need to change the hostname, which defaults to "localhost."
You now know how to create a simple MIDlet, both using the Toolkit, and without it. It's now time to look at the MIDlet lifecycle to understand what actually happens when your MIDlet is deployed and run.
The MIDlet Lifecycle
Mobile devices, whether emulators or real, interact with a MIDlet using their own software, which is called Application Management Software (AMS). The AMS is responsible for initializing, starting, pausing, resuming, and destroying a MIDlet. (Besides these services, AMS may be responsible for installing and removing a MIDlet, as well.) To facilitate this management, a MIDlet can be in one of three states which is controlled via the MIDlet class methods, that every MIDlet extends and overrides. These states are active, paused and destroyed.
Figure 10. The possible states of a MIDlet and the transition between them
As you can see from Figure 11, an installed MIDlet is put into a paused state by the AMS creating an instance of it, by calling its no-args constructor. This is of course, not the only way that the MIDlet can be in a paused state. It can enter this state when the AMS calls the pauseApp() method on an active MIDlet (and the method returns successfully). It can also enter this state when the MIDlet pauses itself by calling the notifyPaused() method, as opposed to the pauseApp() method, which is called by the AMS. However, what exactly is happening with the MIDlet in the paused state?
In a paused state, the MIDlet is waiting for a chance to get into the active state. Theoretically, in this state, it should not be holding or using any of the device resources and should be passive in nature. Once the MIDlet is created, this is the state to be in before becoming active. Also, entering the paused state is necessary when the device requires it to consume fewer resources, because these resources may be required for handling other device functions, like handling an incoming call. This is when the device invokes the pauseApp() method through the AMS. If the MIDlet should inform the AMS that it has paused, it should invoke the notifyPaused() method, which tells the AMS that the MIDlet has indeed paused.
One final way in which a MIDlet can get into a paused state is when the MIDlet's startApp() method, which is called when the AMS invokes it to start the MIDlet (either the first time or from a paused state), throws a MIDletStateChangeException. Essentially, in case of an error, the MIDlet takes the safe road of staying in the paused state.
The active state is where every MIDlet wants to be! This is when the MIDlet can do its functions, hold the device resources and generally, do what it is supposed to do. As said previously, a MIDlet is in an active state when the AMS calls the startApp() method on a paused MIDlet (actually, the MIDlet enters the active state just before this method is called by the AMS). A paused MIDlet can request to go into the active state by calling the method resumeRequest(), which informs the AMS that the MIDlet wishes to become active. The AMS may of course, choose to ignore this request or, alternatively, queue it if there are other MIDlets requesting the same.
The destroyed state is entered when a MIDlet's destroyApp(boolean unconditional) method is called and returns successfully, either from an active or paused state. This method is called by the AMS when it feels that there is no need for the MIDlet to keep running and is the place the MIDlet may perform cleanup and other last minute activities. The MIDlet can enter this state itself, by calling the notifyDestroyed() method, which informs the AMS that the MIDlet has cleaned up its resources and is eligible for destruction. Of course, since in this case, the destroyApp(boolean unconditional) method is not called by the AMS, any last-minute activities must be done before this method is invoked.
What happens if the AMS calls the destroyApp(boolean unconditional) method in the middle of an important step that the MIDlet may be doing, and may be loath to be destroyed? This is where the Boolean unconditional flag comes into the picture. If this flag is set to true, the MIDlet will be destroyed, irrespective of what the MIDlet is doing. However, if this flag is false, effectively, the AMS is telling the MIDlet that it wants the MIDlet to be destroyed, but if the MIDlet is doing something important, it can raise a MIDletStateChangeException, and the AMS will not destroy it just yet. However, note that even then, there are no guarantees that the MIDlet will not be destroyed, and it remains up to each device to decide how they should handle the request. If the device does honor the MIDlet's request, it may try and invoke the destroyApp(boolean unconditional) at a later stage.
Note that a destroyed state means that the MIDlet instance has been destroyed, but not uninstalled from the device. The MIDlet remains installed in the device, and a new instance of it may be created later.
Let me end this section, and this article, with a flow chart of a typical sequence of events while using the DateTimeApp MIDlet that we created in the previous sections, and the corresponding AMS actions and MIDlet states. This flow chart is shown in Figure 11.
Figure 11. AMS actions and MIDlet states through a sequence of events
In the next part of this series, you will start creating useful MIDlets by understanding the User Interface API of MIDP 2.0. This will allow you to create powerful user interfaces, a key requirement for any MIDlet.
Vikram Goyal is the author of Pro Java ME MMAPI.
Related Articles
J2ME Tutorial, Part 4: Multimedia and MIDP 2.0In part four of this J2ME tutorial, you will use the Mobile Media API 1.1 (MMAPI) to load and play audio and video on your MIDP device.
J2ME Tutorial, Part 3: Exploring the Game API of MIDP 2.0In part three of this J2ME tutorial, you will use the mobile gaming package to develop a simple game, which uses all of the classes of this package, as a learning tool.
J2ME Tutorial, Part 2: User Interfaces with MIDP 2.0In part two of the J2ME tutorial you will create the user interface (UI) elements of a MIDlet. Since the interaction with a user is a paramount concern in any MIDlet, due to the size of the screens, it is important for you to understand the basics of this side of MIDlets. Any interaction with a user is done via a UI element.
View all java.net Articles.
Let's use the Toolkit to create the Date-Time MIDlet from the previous section. Click on New Project menu button, and enter the details in the window that comes up, as shown in Figure 6.
Figure 6. Creating a new project
The next window that comes up will allow you to change settings that control the target platform of your MIDlet. In this case, you want to target this MIDlet towards the MIDP 2.0 and CLDC 1.1 platforms and therefore, keep the Target Platform as JTWI, which preselects the MIDP 2.0 Profile. However, you will need to change the Configuration to CLDC 1.1 and uncheck the Optional Mobile Media API library, as shown in Figure 7.
Figure 7. Changing project settings
You can review the rest of the settings by clicking on the tabs at the top, but for the moment, your project is ready to be created. Do so by clicking the OK button at the bottom. The project will be created with information about where to place the project files displayed on the screen, as shown in Figure 8. You can verify that the Toolkit has created a DateTimeApp folder under the apps folder by navigating to it.
Figure 8. Project DateTimeApp created
You have already created the only required src file for this MIDlet in the previous section. Copy this file, DateTimeApp.java, from the folder C:\WTK22\article\com\j2me\part1\ to the fully qualified src folder (C:\WTK22\apps\DateTimeApp\src\com\j2me\part1). Note that the Toolkit created the fully qualified path based on the package name, so you don't have to. Once the copy is done, come back to the Toolkit, and hit the Run menu button. The Toolkit will compile, preverify, and package, and, provided everything goes OK, will run the DateTimeApp in the emulator. Seems simple enough, doesn't it? All you had to do was to create a new project, set the settings, write the code, drop it in the right directory, and hit the Run button. The Toolkit took care of the rest.
Before you leave this section, examine the rest of the folders under the DateTimeApp project. The bin folder under the DateTimeApp folder contains the JAD and the Manifest files, while the classes folder contains compiled classes. But where is the JAR file for this MIDlet? Well, the JAR file is not created by just running (or building) your application in the Toolkit. To create the JAR file, you will need to select the Project menu item, and then select one of the options under the Package submenu, as shown in Figure 9.
Figure 9. Creating the MIDlet's JAR file
By creating this package, the JAR file will be created, with correct Manifest information in the JAD file. You can even create the HTML file that we created in the deploy section previously, by clicking on the Run via OTA (Over The Air) menu. This will not only allow you to simulate your emulator running this MIDlet via the Internet, but also create the HTML file for you in the bin folder. Before you can use this HTML file to deploy on your own server, along with the JAD and the JAR files, you will need to change the hostname, which defaults to "localhost."
You now know how to create a simple MIDlet, both using the Toolkit, and without it. It's now time to look at the MIDlet lifecycle to understand what actually happens when your MIDlet is deployed and run.
The MIDlet Lifecycle
Mobile devices, whether emulators or real, interact with a MIDlet using their own software, which is called Application Management Software (AMS). The AMS is responsible for initializing, starting, pausing, resuming, and destroying a MIDlet. (Besides these services, AMS may be responsible for installing and removing a MIDlet, as well.) To facilitate this management, a MIDlet can be in one of three states which is controlled via the MIDlet class methods, that every MIDlet extends and overrides. These states are active, paused and destroyed.
Figure 10. The possible states of a MIDlet and the transition between them
As you can see from Figure 11, an installed MIDlet is put into a paused state by the AMS creating an instance of it, by calling its no-args constructor. This is of course, not the only way that the MIDlet can be in a paused state. It can enter this state when the AMS calls the pauseApp() method on an active MIDlet (and the method returns successfully). It can also enter this state when the MIDlet pauses itself by calling the notifyPaused() method, as opposed to the pauseApp() method, which is called by the AMS. However, what exactly is happening with the MIDlet in the paused state?
In a paused state, the MIDlet is waiting for a chance to get into the active state. Theoretically, in this state, it should not be holding or using any of the device resources and should be passive in nature. Once the MIDlet is created, this is the state to be in before becoming active. Also, entering the paused state is necessary when the device requires it to consume fewer resources, because these resources may be required for handling other device functions, like handling an incoming call. This is when the device invokes the pauseApp() method through the AMS. If the MIDlet should inform the AMS that it has paused, it should invoke the notifyPaused() method, which tells the AMS that the MIDlet has indeed paused.
One final way in which a MIDlet can get into a paused state is when the MIDlet's startApp() method, which is called when the AMS invokes it to start the MIDlet (either the first time or from a paused state), throws a MIDletStateChangeException. Essentially, in case of an error, the MIDlet takes the safe road of staying in the paused state.
The active state is where every MIDlet wants to be! This is when the MIDlet can do its functions, hold the device resources and generally, do what it is supposed to do. As said previously, a MIDlet is in an active state when the AMS calls the startApp() method on a paused MIDlet (actually, the MIDlet enters the active state just before this method is called by the AMS). A paused MIDlet can request to go into the active state by calling the method resumeRequest(), which informs the AMS that the MIDlet wishes to become active. The AMS may of course, choose to ignore this request or, alternatively, queue it if there are other MIDlets requesting the same.
The destroyed state is entered when a MIDlet's destroyApp(boolean unconditional) method is called and returns successfully, either from an active or paused state. This method is called by the AMS when it feels that there is no need for the MIDlet to keep running and is the place the MIDlet may perform cleanup and other last minute activities. The MIDlet can enter this state itself, by calling the notifyDestroyed() method, which informs the AMS that the MIDlet has cleaned up its resources and is eligible for destruction. Of course, since in this case, the destroyApp(boolean unconditional) method is not called by the AMS, any last-minute activities must be done before this method is invoked.
What happens if the AMS calls the destroyApp(boolean unconditional) method in the middle of an important step that the MIDlet may be doing, and may be loath to be destroyed? This is where the Boolean unconditional flag comes into the picture. If this flag is set to true, the MIDlet will be destroyed, irrespective of what the MIDlet is doing. However, if this flag is false, effectively, the AMS is telling the MIDlet that it wants the MIDlet to be destroyed, but if the MIDlet is doing something important, it can raise a MIDletStateChangeException, and the AMS will not destroy it just yet. However, note that even then, there are no guarantees that the MIDlet will not be destroyed, and it remains up to each device to decide how they should handle the request. If the device does honor the MIDlet's request, it may try and invoke the destroyApp(boolean unconditional) at a later stage.
Note that a destroyed state means that the MIDlet instance has been destroyed, but not uninstalled from the device. The MIDlet remains installed in the device, and a new instance of it may be created later.
Let me end this section, and this article, with a flow chart of a typical sequence of events while using the DateTimeApp MIDlet that we created in the previous sections, and the corresponding AMS actions and MIDlet states. This flow chart is shown in Figure 11.
Figure 11. AMS actions and MIDlet states through a sequence of events
In the next part of this series, you will start creating useful MIDlets by understanding the User Interface API of MIDP 2.0. This will allow you to create powerful user interfaces, a key requirement for any MIDlet.
Vikram Goyal is the author of Pro Java ME MMAPI.
Related Articles
J2ME Tutorial, Part 4: Multimedia and MIDP 2.0In part four of this J2ME tutorial, you will use the Mobile Media API 1.1 (MMAPI) to load and play audio and video on your MIDP device.
J2ME Tutorial, Part 3: Exploring the Game API of MIDP 2.0In part three of this J2ME tutorial, you will use the mobile gaming package to develop a simple game, which uses all of the classes of this package, as a learning tool.
J2ME Tutorial, Part 2: User Interfaces with MIDP 2.0In part two of the J2ME tutorial you will create the user interface (UI) elements of a MIDlet. Since the interaction with a user is a paramount concern in any MIDlet, due to the size of the screens, it is important for you to understand the basics of this side of MIDlets. Any interaction with a user is done via a UI element.
View all java.net Articles.
Không có nhận xét nào:
Đăng nhận xét