[MicroUI] system generates ej.microui.io.OutOfEventsException

Introduction

MicroUI is based on a notion of events, generated by a stack of events. This stack has a fixed size, by default 100 events; a thread is in charge of unstacking those events. OutOfEventsException is raised when this buffer is filled. It means that the stack receive events faster than the system can handle them.

An event is generated when:

  • A MicroUI Displayable.repaint() function is called.
  • A MicroUI__Display.callSerially()__ block is used.
  • A MWT Widget.revalidate() function is called.
  • An event is generated by the platform (eg touch).

An event is consumed when:

  • A MicroUI__Display.callSerially()__ block ends
  • an event is handled (typically when a EventHandler.handleEvent() function returns true).

How to avoid it?

Check the software architecture

Often OutOfEventsException are due to poor software architecture, one event (such as a touch on a button) induce many other events. So when the user presses rapidly and repeatedly a button, the system cannot handle the events.

For instance, for a typical UI with :

  • one button in a page
  • one menu
  • and one notification page

This is the sequence of events that may be triggered :

  • The user presses a button (One touch event)
  • The UI change the colour of the button (One repaint event)
  • The user release the button (One touch event)
  • The UI changes the page (four Events):
    • The UI revalidates all the page (One revalidate event)
    • The button is revalidated (One revalidate event)
    • The menu bar is revalidated (One revalidate event)
    • The notification bar is revalidated (One revalidate event)

If the user pressed repeatedly this button, the seven events will be generated on each button press.

A good architecture should:

  • Avoid useless repaint/revalidate (do the notification bar and menu need to be revalidated?).
  • Avoid long callSerially blocks.

Avoid long event handlers

Another common case of OutOfEventException is when a function handle event is long to process (for instance, if it goes through a long list or requires a lot of computation). In this case it is recommended to delegate this actions to another thread.

Can OutOfEventsException exceptions be caught?

OutOfEventsException exceptions do not go through the default exception handler as the display pump is required. So the MicroEJ JVM stops.

I still get OutOfEventsException exception, what can I do?

  • Increase the size of the buffer of events.

It is defined in the Run configuration (in MicroEJ : run configuration -> Configuration -> Memory -> Native events queue size).

  • Reset the system when receiving an OutOfEventsException exception.

A watchdog can be used. It is fed periodically with a SNI call in a function generating an event (callSerially, repaint, revalidate).

I get OutOfEventsException in the simulator debugger when I set a breakpoint, what can I do?

By default breakpoint will only suspend the current Java thread in the debugger, the other threads are still running and OutOfEventsException can be triggered.
By right clicking on the breakpoint in the SDK IDE, select Breakpoint properties and set “Suspend VM” will suspend all threads.
To change the default behavior when setting breakpoints, go to Window > Preferences > Java Debug > change the Default suspend policy for new breakpoints to “Suspend VM”.