midletstatehandler.java
来自「This is a resource based on j2me embedde」· Java 代码 · 共 801 行 · 第 1/2 页
JAVA
801 行
/* * * * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */package com.sun.midp.midlet;import javax.microedition.midlet.MIDlet;import javax.microedition.midlet.MIDletStateChangeException;import com.sun.j2me.security.AccessController;import com.sun.midp.security.Permissions;import com.sun.midp.security.SecurityToken;import com.sun.midp.log.Logging;import com.sun.midp.log.LogChannels;/** * The MIDletStateHandler starts and controls MIDlets through the lifecycle * states. * MIDlets are created using its no-arg Constructor. Once created * a MIDlet is sequenced through the <code>ACTIVE</code>, * <code>PAUSED</code>, and <code>DESTROYED</code> states. * <p> * The MIDletStateHandler is a singleton for the suite being run and * is retrieved with getMIDletStateHandler(). This allow the * MIDletStateHandler to be the anchor of trust internally for the MIDP API, * restricted methods can obtain the MIDletStateHandler for a MIDlet suite * inorder to check the properties and actions of a suite. * Because of this, there MUST only be one a MIDlet suite per * MIDletStateHandler. In addition a method can assume that the application * manager is the caller if there is no suite started.</p> * <p> * The MIDlet methods are protected in the javax.microedition.midlet package * so the MIDletStateHandler can not call them directly. The MIDletState * object and * MIDletTunnel subclass class allow the MIDletStateHandler to hold the state * of the * MIDlet and to invoke methods on it. The MIDletState instance is created * by the MIDlet when it is constructed. * <p> * This implementation of the MIDletStateHandler introduces * extra internal MIDlet states to allow processing of MIDlet * requested state changes in the control thread and serialized with * other state changes. The additional states are: * <UL> * <LI> <code>ACTIVE_PENDING</code> - The MIDlet is still PAUSED but * will be <code>ACTIVE</code> after startApp is called when the state is * next processed. * <LI> <code>PAUSE_PENDING</code> - The MIDlet is still ACTIVE but * will be <code>PAUSED</code> after pauseApp is called when the state is * next processed. * <LI> <code>DESTROY_PENDING</code> - Indicates that the MIDlet needs * to be <code>DESTROYED</code>. The MIDlet's destroyApp has not yet been * called. * </UL> * The MIDletStateHandler loops, looking for MIDlets that require state changes * and making the requested changes including calling methods in * the MIDlet to make the change. * <p> * When a MIDlet's state is changed to <code>ACTIVE</code>, * <code>PAUSED</code>, or <code>DESTROYED</code> the MIDlet state listener * is notified of the change, which in turn sends the notification onto * the central AMS. * * @see MIDlet * @see MIDletPeer * @see MIDletLoader * @see MIDletStateHandler */public class MIDletStateHandler { /** the current MIDlet suite. */ private MIDletSuite midletSuite; /** loads the MIDlets from a suite's JAR in a VM specific way. */ private MIDletLoader midletLoader; /** array of MIDlets. */ private MIDletPeer[] midlets; /** current number of MIDlets [0..n-1]. */ private int nmidlets; /** next index to be scanned by selectByPriority. */ private int scanIndex; /** The event handler of all MIDlets in an Isolate. */ private static MIDletStateHandler stateHandler; /** The listener for the state of all MIDlets in an Isolate. */ private static MIDletStateListener listener; /** Serializes the creation of MIDlets. */ private static Object createMIDletLock = new Object(); /** New MIDlet peer waiting for the next MIDlet created to claim it. */ private static MIDletPeer newMidletPeer; /** MIDlet peer for MIDlet being constructed but not registered yet. */ private MIDletPeer underConstructionPeer; /** * Construct a new MIDletStateHandler object. */ private MIDletStateHandler() { nmidlets = 0; // start with 5 empty slots, we will add more if needed midlets = new MIDletPeer[5]; } /** * Gets the MIDletStateHandler that manages the lifecycle states of * MIDlets running in an Isolate. * <p> * If the instance of the MIDletStateHandler has already been created * it is returned. If not it is created. * The instance becomes the MIDletStateHandler for this suite. * <p> * The fact that there is one handler per Isolate * is a security feature. Also a security feature, is that * getMIDletStateHandler is * static, so API can find out what suite is calling, if in the future * multiple suites can be run in the same VM, the MIDlet state handler * for each suite * should be loaded in a different classloader or have some other way * having multiple instances of static class data. * * @return the MIDlet state handler for this Isolate */ public static synchronized MIDletStateHandler getMidletStateHandler() { /* * If the midlet state handler has not been created, create one now. */ if (stateHandler == null) { /* This is the default scheduler class */ stateHandler = new MIDletStateHandler(); } return stateHandler; } /** * Initializes MIDlet State Handler. * * @param token security token for initilaization * @param theMIDletStateListener processes MIDlet states in a * VM specific way * @param theMidletLoader loads a MIDlet in a VM specific way * @param thePlatformRequestHandler the platform request handler */ public void initMIDletStateHandler( SecurityToken token, MIDletStateListener theMIDletStateListener, MIDletLoader theMidletLoader, PlatformRequest thePlatformRequestHandler) { token.checkIfPermissionAllowed(Permissions.AMS); listener = theMIDletStateListener; midletLoader = theMidletLoader; MIDletPeer.initClass(this, listener, thePlatformRequestHandler); } /** * Starts a MIDlet from outside of the package. * * @param classname name of MIDlet class * @param displayName name to show the user * * @exception SecurityException if the suite does not have the * AMS permission. * @exception ClassNotFoundException is thrown, if the MIDlet main class is * not found * @exception InstantiationException is thrown, if the MIDlet can not be * created * @exception IllegalAccessException is thrown, if the MIDlet is not * permitted to perform a specific operation */ public void startMIDlet(String classname, String displayName) throws ClassNotFoundException, InstantiationException, IllegalAccessException { startMIDlet(0, classname, displayName); } /** * Starts a MIDlet from outside of the package. * <p> * Method requires com.sun.midp.ams permission. * * @param externalAppId ID of given by an external application manager * @param classname name of MIDlet class * @param displayName name to show the user * * @exception SecurityException if the suite does not have the * AMS permission. * @exception ClassNotFoundException is thrown, if the MIDlet main class is * not found * @exception InstantiationException is thrown, if the MIDlet can not be * created * @exception IllegalAccessException is thrown, if the MIDlet is not * permitted to perform a specific operation */ public void startMIDlet(int externalAppId, String classname, String displayName) throws ClassNotFoundException, InstantiationException, IllegalAccessException { AccessController.checkPermission(Permissions.AMS_PERMISSION_NAME); createAndRegisterMIDlet(externalAppId, classname); } /** * Starts a MIDlet from outside of the package. * * @param token security token of the caller * @param classname name of MIDlet class * @param displayName name to show the user * * @exception SecurityException if the caller does not have the * AMS permission. * @exception ClassNotFoundException is thrown, if the MIDlet main class is * not found * @exception InstantiationException is thrown, if the MIDlet can not be * created * @exception IllegalAccessException is thrown, if the MIDlet is not * permitted to perform a specific operation */ public void startMIDlet(SecurityToken token, String classname, String displayName) throws ClassNotFoundException, InstantiationException, IllegalAccessException { startMIDlet(token, 0, classname, displayName); } /** * Starts a MIDlet from outside of the package. * * @param token security token of the caller * @param externalAppId ID of given by an external application manager * @param classname name of MIDlet class * @param displayName name to show the user * * @exception SecurityException if the caller does not have the * AMS permission. * @exception ClassNotFoundException is thrown, if the MIDlet main class is * not found * @exception InstantiationException is thrown, if the MIDlet can not be * created * @exception IllegalAccessException is thrown, if the MIDlet is not * permitted to perform a specific operation */ public void startMIDlet(SecurityToken token, int externalAppId, String classname, String displayName) throws ClassNotFoundException, InstantiationException, IllegalAccessException { token.checkIfPermissionAllowed(Permissions.AMS); createAndRegisterMIDlet(externalAppId, classname); } /** * Gets the class name first midlet in the list of running MIDlets. * * @return the classname or null if no midlet are running */ public String getFirstRunningMidlet() { synchronized (this) { if (nmidlets <= 0) { return null; } return midlets[0].midlet.getClass().getName(); } } /** * Registers a MIDlet being constructed. * * @param midlet to be registered with this state handler */ private void register(MIDlet midlet) { synchronized (this) { MIDletPeer state = MIDletPeer.getMIDletPeer(midlet); /* * If a MIDlet of the same class is already running * Make the existing MIDlet current so that startSuite() * will run it */ int i = findMIDletByClass(state); if (i >= 0) { state.setState(MIDletPeer.DESTROY_PENDING); // Fall into adding it to the list so destroyApp // can be called at a reasonable time. } // Grow the list if necessary if (nmidlets >= midlets.length) { MIDletPeer[] n = new MIDletPeer[nmidlets+5]; System.arraycopy(midlets, 0, n, 0, nmidlets); midlets = n; } // Add it to the end of the list midlets[nmidlets++] = state; // MIDlet peer is registered now underConstructionPeer = null; this.notify(); } } /** * Creates and register MIDlet with VM notification * of the MIDlet's startup phase. * * @param externalAppId ID of given by an external application manager * @param classname name of MIDlet class * * @exception ClassNotFoundException if the MIDlet class is * not found * @exception InstantiationException if the MIDlet cannot be * created * @exception IllegalAccessException if the MIDlet is not * permitted to perform a specific operation */ private void createAndRegisterMIDlet(int externalAppId, String classname) throws ClassNotFoundException, InstantiationException, IllegalAccessException { listener.midletPreStart(getMIDletSuite(), classname); register(createMIDlet(externalAppId, classname)); } /** * Provides a object with a mechanism to retrieve * <code>MIDletSuite</code> being run. * * @return MIDletSuite being run */ public MIDletSuite getMIDletSuite() { return midletSuite; } /** * Runs MIDlets until there are none. * Handle any pending state transitions of any MIDlet. * If there are none, wait for transitions. * * @param exceptionHandler the handler for midlet execution exceptions. * @param aMidletSuite the current midlet suite * @param externalAppId ID of given by an external application manager * @param classname name of MIDlet class * * @exception ClassNotFoundException is thrown, if the MIDlet main class is * not found * @exception InstantiationException is thrown, if the MIDlet can not be * created * @exception IllegalAccessException is thrown, if the MIDlet is not * permitted to perform a specific operation */ public void startSuite(MIDletSuiteExceptionListener exceptionHandler, MIDletSuite aMidletSuite, int externalAppId, String classname) throws ClassNotFoundException, InstantiationException, IllegalAccessException { if (midletSuite != null) { throw new RuntimeException( "There is already a MIDlet Suite running."); } midletSuite = aMidletSuite; createAndRegisterMIDlet(externalAppId, classname); /* * Until there are no MIDlets * Scan all the MIDlets looking for state changes. */ while (nmidlets > 0) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?