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 + -
显示快捷键?