📄 scheduler.java
字号:
setForeground(newfg, true); } // Scan all the MIDlets looking for state changes. synchronized (mutex) { /* * Find the highest priority state of any MIDlet and * process */ MIDletState curr = selectByPriority(); switch (curr.getState()) { case MIDletState.ACTIVE: case MIDletState.PAUSED: case MIDletState.ACTIVE_FOREGROUND: // Wait for some change in the state of a MIDlet // that needs attention try { mutex.wait(); } catch (InterruptedException e) { } break; case MIDletState.PAUSED_RESUME: // Start the MIDlet if needed try { curr.setState(MIDletState.ACTIVE); curr.startApp(); } catch (Exception ex) { printException("startApp 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); } curr.setState(MIDletState.DESTROYED); // Fall into DESTROYED cleanup case MIDletState.DESTROYED: unregister(curr); break; default: throw new Error("Illegal MIDletState state " + curr.getState()); } } } catch (Exception ex) { System.out.println("Exception in schedule"); ex.printStackTrace(); } } midletSuite = null; } /** * Look through the current MIDlets and select one to * be in foreground. * <p>Note: that this method is called while synchronized on "mutex". * @return the MIDlet to make foreground, null is returned if none. */ 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; } /** * Look through the current MIDlets and select one to * be in foreground. If none is found the previous foreground * is returned if it is an ACTIVE MIDlet. * Any MIDlet with a non-null current * Screen is preferred over one without a displayable. * <p>Note: This method is called while synchronized on "mutex". * @param oldfg old foreground state of the MIDlet * @return the MIDlet to make foreground, null is returned if none. */ private MIDletState selectForeground(MIDletState oldfg) { MIDletState found = null; // Chosen MIDletState // Find an active MIDlet that has a current Displayable for (int i = nmidlets-1; i >= 0; i--) { if (midlets[i].getState() == MIDletState.ACTIVE) { found = midlets[i]; // If it has a non-null Display then it is the one to use if (found.getDisplayAccess().hasCurrent()) { return found; } } } // No MIDlet with a current Displayable // If the old foreground MIDlet is ACTIVE; use it if (oldfg != null && oldfg.getState() == MIDletState.ACTIVE) { return oldfg; } // Return the ACTIVE MIDlet found (if any) return found; } /** * Called to notify the scheduler that the current Displayable * has changed. * If it is the current foreground MIDlet and hasCurrent is false * then its state is changed from ACTIVE_FOREGROUND to ACTIVE * to allow another MIDlet to be made foreground. * If the current foreground MIDlet does not have a current Display * and this transition is for MIDlet that has a display demote * the current MIDlet to the new one can be selected. * @param displayAccess the Display accessor of the Display being changed * @param hasCurrent is true if the Displable is being set to non-null, * <code>false</code> otherwise. */ public void notifyHasCurrent(DisplayAccess displayAccess, boolean hasCurrent) { synchronized (mutex) { if (foreground != null) { DisplayAccess fda = foreground.getDisplayAccess(); if (fda == displayAccess) { // This change is for the current display // If foreground has set its Display to null if (hasCurrent == false && (foreground.getState() == MIDletState.ACTIVE_FOREGROUND)) { foreground.setState(MIDletState.ACTIVE); } } else { // For another Display that is not in foreground // some other Display has a displayable // If the current one doesn't, consider a switch if (hasCurrent && (!fda.hasCurrent()) && foreground.getState() == MIDletState.ACTIVE_FOREGROUND) { foreground.setState(MIDletState.ACTIVE); } } } mutex.notify(); } } /** * The Scheduler is notified to stop the foreground MIDlet. * Destroy the foreground MIDlet only if it the "end" key was * pressed on the correct Display. * @param displayAccess the DisplayAccess of the MIDlet to be killed. * * @see javax.microedition.lcdui.Display */ public void notifyEnd(DisplayAccess displayAccess) { synchronized (mutex) { if (foreground != null) { /* * Ignore requests to kill anything but the correct * foreground MIDlet */ if (foreground.getDisplayAccess() != displayAccess) { return; } foreground.setState(MIDletState.DESTROY_PENDING); // start at the top of the list, when finding the next midlet scanIndex = 0; } } } /** * Return true if the specified MIDlet is in the foreground. * @param midlet to be checked for foreground attribute * @return true if the midlet is non-null and matches scheduler * current foreground midlet */ protected static boolean hasForeground(MIDletState midlet) { return (midlet != null && midlet == scheduler.foreground); } /** * Give the specified MIDlet the foreground. * Note: This method must <em>NOT</em> be called while holding * the mutex. Doing so may deadlock with the locks held * in the Display. * @param midlet to assign as scheduler foreground midlet. * @param foreground flag is true to request foreground or * false to release foreground. */ private static void setForeground(MIDletState midlet, boolean foreground) { // Change the state of the specified MIDlets Display midlet.getDisplayAccess().setForeground(foreground); } /** * 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; MIDLetMap.remove(m.getMIDlet()); 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 + -