📄 scheduler.java
字号:
getDisplayManager().addSystemEventListener(this); midletSuite = aMidletSuite; register( MIDletState.createMIDlet(midletSuite.getInitialMIDletClassname())); /* * Until there are no MIDlets * Scan all the MIDlets looking for state changes. */ while (nmidlets > 0) { try { MIDletState curr; int state; synchronized (mutex) { /* * Find the highest priority state of any MIDlet and * process, but do not hold the lock while processing * to avoid deadlocks with LCDUI and event handling. * Perform state changes with a lock so * no state changes are lost. */ curr = selectByPriority(); state = curr.getState(); switch (state) { case MIDletState.ACTIVE: // fall through case MIDletState.PAUSED: // Wait for some change in the state of a MIDlet // that needs attention try { mutex.wait(); } catch (InterruptedException e) { } continue; case MIDletState.PAUSED_RESUME: // fall through case MIDletState.ACTIVE_PENDING: // Start the MIDlet curr.setStateWithoutNotify(MIDletState.ACTIVE); break; case MIDletState.PAUSE_PENDING: // The display manager wants the MIDlet paused curr.setStateWithoutNotify(MIDletState.PAUSED); break; case MIDletState.DESTROY_PENDING: curr.setStateWithoutNotify(MIDletState.DESTROYED); break; case MIDletState.DESTROYED: unregister(curr); break; default: throw new Error("Illegal MIDletState state " + curr.getState()); } } /* perform work that may block outside of the mutex. */ switch (state) { case MIDletState.PAUSED_RESUME: getDisplayManager().activate(this, curr.getMIDlet()); // fall through case MIDletState.ACTIVE_PENDING: try { curr.startApp(); } catch (Exception ex) { printException("startApp threw an Exception", ex); curr.setState(MIDletState.DESTROY_PENDING); } break; case MIDletState.PAUSE_PENDING: try { curr.pauseApp(); } catch (Exception ex) { printException("pauseApp threw an Exception", ex); curr.setState(MIDletState.DESTROY_PENDING); } break; case MIDletState.DESTROY_PENDING: // If the MIDlet is in the DESTROY_PENDING state // call its destroyApp method to clean it up. try { // Tell the MIDlet to cleanup. curr.destroyApp(true); } catch (MIDletStateChangeException ex) { // Ignore the exception } catch (Exception ex) { printException("destroyApp threw an Exception", ex); } break; case MIDletState.DESTROYED: getDisplayManager().deactivate(curr.getMIDlet()); break; } } catch (Exception ex) { System.out.println("Exception in schedule"); ex.printStackTrace(); } } midletSuite.saveSettings(); midletSuite = null; getDisplayManager().releaseSystemEventListener(this); return !systemShutdown; } /** * Shutdown all running MIDlets and prepare the MIDP runtime * to exit completely. */ public void shutdown() { synchronized (mutex) { systemShutdown = true; for (int i = 0; i < nmidlets; i++) { if (midlets[i].getState() != MIDletState.DESTROYED) { midlets[i]. setStateWithoutNotify(MIDletState.DESTROY_PENDING); } } mutex.notify(); } } /** * Check if the named <code>MIDlet</code> has already been instantiated. * @param name class name of <code>MIDlet</code> to test if * currently scheduled * @return <code>true</code> if an instance of the MIDlet is already * running */ public boolean isScheduled(String name) { boolean found = false; synchronized (mutex) { for (int i = 0; i < nmidlets; i++) { if (midlets[i].getMIDlet().getClass().getName().equals(name)) { found = true; break; } } } return found; } /** * Pause the current foreground MIDlet and return to the * AMS or "selector" to possibly run another MIDlet in the * currently active suite. Currently, the RI does not support * running multiple MIDlets, but if it did, this system * callback would allow it. The listener should not deactivate * the display of the MIDlet. * * @param midlet midlet that the event applies to */ public void pauseMIDlet(MIDlet midlet) { MIDletState state = MIDletStateMap.getState(midlet); state.setState(MIDletState.PAUSE_PENDING); } /** * Start the currently suspended state. This is a result * of the underlying system returning control to MIDP. * Any previously paused foreground MIDlet will be restarted * and the Display will be refreshed. The listener should not activate * the display of the MIDlet since this will be done automatically. * * @param midlet midlet that the event applies to */ public void startMIDlet(MIDlet midlet) { MIDletState state = MIDletStateMap.getState(midlet); state.setState(MIDletState.ACTIVE_PENDING); } /** * Destroy the MIDlet given midlet. Return to the control to * AMS if there are no another active MIDlets in the * scheduled. This is a system callback which * allows a user to forcibly exit a running MIDlet in cases * where it is necessary (such as a rogue MIDlet which does * not provide exit capability). * * @param midlet midlet that the event applies to */ public void destroyMIDlet(MIDlet midlet) { MIDletState state = MIDletStateMap.getState(midlet); state.setState(MIDletState.DESTROY_PENDING); } /** * Look through the current MIDlets and select one to * be processed. * <p>Note: that this method is called while synchronized on "mutex". * @return the MIDlet to process next */ private MIDletState selectByPriority() { MIDletState found = null; // Chosen MIDletState int state = -1; // the state of the chosen MIDlet /* * Find the most desirable MIDlet based on its state * The higher state values are preferred because they * are needed for cleanup. */ for (int i = nmidlets-1; i >= 0; i--) { // make sure index is inside current array, favoring the end if (scanIndex < 0 || scanIndex >= nmidlets) scanIndex = nmidlets-1; // Pick this MIDlet if the state is higher priority int s = midlets[scanIndex].getState(); if (s > state) { found = midlets[scanIndex]; state = s; } scanIndex--; } return found; } /** * Remove a MIDlet from the list if it is there, * otherwise ignore the request. * Call only while synchronized on mutex. * @param m the MIDlet to remove */ private void unregister(MIDletState m) { // Find it in the list and switch the last one for it. for (int i = 0; i < nmidlets; i++) { if (m == midlets[i]) { // Switch the last MIDlet into that offset. midlets[i] = midlets[nmidlets-1]; // null out from array and remove from map to allow for GC midlets[--nmidlets] = null; break; } } } /** * Find a MIDlet in the list by it class. * Only a single MIDlet of a class can be active at * a time. * Must be called synchronized on the mutex. * @param m the MIDlet to find * @return the index in the array of MIDlets. * return -1 if the MIDlet is not found. */ private int findMIDletByClass(MIDletState m) { // Find it in the list for (int i = 0; i < nmidlets; i++) { if (m.getMIDlet().getClass() == midlets[i].getMIDlet().getClass()) { return i; } } return -1; } /** * Print an exception with a reason. * Should be logged instead. * @param msg string to associate with the current exception * @param ex the exception to be reported */ private static void printException(String msg, Exception ex) { try { System.out.println(msg); if (ex.getMessage() == null) { System.out.println(ex); } ex.printStackTrace(); } catch (Exception e) { } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -