⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scheduler.java

📁 有关j2me的很好的例子可以研究一下
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * @(#)Scheduler.java	1.50 01/08/08 * Copyright (c) 1999,2001 Sun Microsystems, Inc. All Rights Reserved. * * This software is the confidential and proprietary information of Sun * Microsystems, Inc. ("Confidential Information").  You shall not * disclose such Confidential Information and shall use it only in * accordance with the terms of the license agreement you entered into * with Sun. * * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING * THIS SOFTWARE OR ITS DERIVATIVES. */package com.sun.midp.midlet;import javax.microedition.midlet.MIDlet;import javax.microedition.midlet.MIDletStateChangeException;import com.sun.midp.lcdui.MIDLetMap;import com.sun.midp.lcdui.DisplayAccess;import com.sun.midp.Configuration;/** * The Scheduler starts and controls MIDlets through the lifecycle states. * MIDlets are created using its no-arg Constructor. Once created  * it is sequenced through the start, paused, and destroy states. * It handles transitions of the Display between foreground and background. * <p> * The Scheduler is a singleton. The Scheduler is retrieved with * getScheduler().  The Scheduler can be replaced by subclassing. * Events that affect MIDlet scheduling should notify the Scheduler. * Typical events are MIDlet creation, changing of MIDlet states, changes * in the status of the current Displayable, etc. * <p> * To replace the Scheduler, subclass it and then set the  * "com.sun.midp.midlet.scheduler" property to the name of the subclass. * When the Scheduler is first retrieved, the property is checked and the * instance created.  If left unset the Scheduler class is used unchanged. * <p> * The MIDlet methods are protected in the javax.microedition.midlet package * so the Scheduler can not call them directly.  The MIDletState object and * MIDletProxy subclass class allow the Scheduler 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 default implementation of the Scheduler introduces a couple * of extra internally only visible 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_FOREGROUND</code> - Similar to ACTIVE but also * indicates that this MIDlet has the Display (i.e. is in foreground). * <LI> <code>PAUSED_RESUME</code> - Similar to PAUSED but also indicates * that this MIDlet has requested to be resumed. * <LI> <code>DESTROY_PENDING</code> - Indicates that the MIDlet needs * to be DESTROYED. The MIDlet's destroyApp has not yet been called. * </UL> * The Scheduler loops, looking for MIDlets that require state changes * and making the requested changes including calling methods in * the MIDlet to make the change. * <p> * Transitions in the foreground and background status are handled based * on events delivered from the Display that signal changes in the * current Displayable on the Display and on the current state of the * MIDlet. Specifically: * <UL> * <LI> Only the MIDlet in state ACTIVE_FOREGROUND is in foreground. * Any state change (paused, destroyed, etc) causes foreground to  * be revoked. The current foreground MIDlet is checked on each loop. * (Another will be selected later). * <LI> If there is no foreground MIDlet a search is made for an ACTIVE * MIDlet that has set a "current" displayable (that is non-null). * There is no particular ordering or priority or cycling behavior * in the implementation. * If a MIDlet is found it is set into ACTIVE_FOREGROUND state and * given the Display. * <LI> It is possible that as far as the Scheduler is concerned * there will be no foreground MIDlet.  The only case in which this should  * arise is when all MIDlets are PAUSED or DESTROYED.  From the user * point of view this is quite bad. It is avoided by always having * the Selector be ACTIVE and able to be selected. * <LI>The notifyEnd event causes the foreground MIDlet to be * put into DestroyPending state.  (Exception that the "Selector" * is never killed.) This simulates the behavior that pressing the * "end" key on the phone will return the display to the Selector. * </UL> * @see MIDlet * @see MIDletState */public class Scheduler {    /** the current MIDlet suite */    private MIDletSuite midletSuite;    /** the current foreground MIDlet */    private MIDletState foreground;    /** array of MIDlets */    private MIDletState[] midlets;    /** current number of MIDlets [0..n-1] */    private int nmidlets;           /**  next index to be scanned by selectForeground */    private int scanIndex;          /** used to wait for MIDlet state changes */    private static Object mutex;     /** the manager of all MIDlets */    private static Scheduler scheduler;     /**     * Construct a new Scheduler object.     */    protected Scheduler() {        /*         * The fact that there is only one scheduler is a security feature.         * Multiple schedulers are allow in the future, the constructor         * should require security domain parameter and it should be         * checked.         */        if (scheduler != null)            throw new Error("Only one scheduler instance allowed");        mutex = new Object();        nmidlets = 0;        // start with 5 empty slots, we will add more if needed        midlets = new MIDletState[5];    }    /**     * Get the Scheduler that manages the lifecycle states MIDlets.     * If the instance of the Scheduler has already been created     * it is returned.  If not it is created from the value of      * the "com.sun.midp.midlet.scheduler" property.  If that property     * is null the default scheduler (this class) is instantiated.     * The instance becomes the Scheduler for this process     * @return the MIDlet management software scheduler     */    public static synchronized Scheduler getScheduler() {        /*         * If not scheduler has been created, create one now.         * If the scheduler class has been overridden use it.         */        if (scheduler == null) {            String prop =                Configuration.getProperty("com.sun.midp.midlet.scheduler");            if (prop != null) {                try {                    scheduler = (Scheduler)(Class.forName(prop)).newInstance();                } catch (Throwable ex) {                    throw new Error("A scheduler cannot be created from " +                                     "the value of property " +                                    "com.sun.midp.midlet.scheduler");                }            } else {                /* This is the default scheduler class */                scheduler = new Scheduler();            }        }        return scheduler;    }    /**     * Register a MIDlet being constructed.     * Called from the MIDlet constructor so Scheduler knows every     * existing MIDlet.     * @param midlet to be registered with this scheduler     */    protected void register(MIDletState midlet) {        synchronized (mutex) {            /*             * If a MIDlet of the same class is already running             * Make the existing MIDlet current so that schedule() will run it             */            int i = findMIDletByClass(midlet);            if (i >= 0) {                midlet.setState(MIDletState.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) {                MIDletState[] n = new MIDletState[nmidlets+5];                System.arraycopy(midlets, 0, n, 0, nmidlets);                midlets = n;            }            // Add it to the end of the list            midlets[nmidlets++] = midlet;        }    }    /**     * Return the mutex for synchronization and notification of changes      * to a MIDlets state.     * It is used by MIDlets when they are changing states.     * It is the mutex used for all state changes.     * @return mutex object for synchronizing this scheduler     */    protected Object getMutex() {        return mutex;    }    /**     * Provides a <code>MIDletProxy</code> with a mechanism to retrieve     * <code>MIDletSuite</code> being scheduled.     *     * @return MIDletSuite being scheduled     */    public MIDletSuite getMIDletSuite() {        return midletSuite;    }    /**     * Run MIDlets until there are none.     * Handle any pending state transitions of any MIDlet.     * If there are none, wait for transitions.     * If there is no foreground MIDlet select one that is ACTIVE and     * has setCurrent != null.     * <p>     * If the foreground MIDlet changes from the ACTIVE_FOREGROUND state     * it automatically looses the foreground and and new one is selected.     * @param aMidletSuite the current midlet suite     * @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 schedule(MIDletSuite aMidletSuite) throws        ClassNotFoundException, InstantiationException,        IllegalAccessException {        if (midletSuite != null) {            throw new RuntimeException(                "There is already a MIDlet Suite scheduled.");        }        midletSuite = aMidletSuite;                midletSuite.loadInitialMIDlet();        // Until there are no MIDlets        while (nmidlets > 0) {            try {                MIDletState oldfg, newfg;                // Check if a change in foreground is needed                synchronized (mutex) {                    // Check if the foreground MIDlet has                    // changed state and should not be foreground anymore                    oldfg = null;                    if (foreground != null &&                        foreground.getState() !=                            MIDletState.ACTIVE_FOREGROUND) {                        oldfg = foreground;                        foreground = null;                    }                    newfg = null;                    if (foreground == null) {                        // No MIDlet as foreground                        // Scan the actives looking for one that needs/wants                        // the display                        foreground = selectForeground(oldfg);                        if (foreground != null) {                            // set the MIDlet in the ACTIVE_FOREGROUND state                            foreground.setState(MIDletState.ACTIVE_FOREGROUND);                            newfg = foreground;                        }                    }                }                // If foreground needs to be revoked do so outside of mutex                if (oldfg != null) {                    setForeground(oldfg, false);                }                // If foreground needs to be invoked do so outside of mutex                if (newfg != null) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -