Events in Brew
The Brew Application Execution Environment (AEE) includes an event pump that accepts events from the system and other sources and directs them to applications. Using the twin methods ISHELL_SendEvent
, your application can direct an event to any other application resident on the device. With the eventa thirty-two bit integeryou can send two arguments: a sixteen bit integer and a thirty-two bit integer, collectively called the event arguments. The system reserves a range of events for system notifications such as incoming keystrokes, alarms, and SMS messages; any event numbered greater than the Brew-defined constant EVT_USER
is fair game.
When sending an event to another application, it's important to know the difference between ISHELL_SendEvent and ISHELL_PostEvent. The former is synchronous, that is, the recipient's event handler is invoked before ISHELL_SendEvent returns. ISHELL_PostEvent, on the other hand, is asynchronous; your event is queued and will be sent to the recipient application after ISHELL_PostEvent returns. Which you choose to use is largely up to you, but you should be aware of two things:
- Because ISHELL_SendEvent is synchronous, the amount of stack space available to the recipient may be significantly less than if you use ISHELL_PostEvent.
- Anything you're signalling about using ISHELL_PostEvent must persist beyond the lifetime of the calling function, because it's asynchronous and the receiver won't receive the event until your application has yielded control to the Brew run time.
An obvious mode of interapplication communication, then, is to agree on event code and argument syntax, and just have two applications pass events around. If you and I agree that EVT_USER+1
means somethingsay, for my application to show a particular screenyour application can invoke mine by sending me that event, and I can handle it by launching using ISHELL_StartApplet
and going to that screen.
This is unnecessarily brittle, however. Brew provides the ISHELL_RegisterEvent call, which takes a character string and returns a unique event associated with that character string. If more than one application invokes this API with the same character string, the same event is returned. Thus, instead of agreeing on a specific constant (EVT_USER+1) it's better for us to agree on a well-defined character string, such as com.rocketmobile.myapp.launchtolistview, and let Brew handle the event code mapping under the hood. On boot, my application can register this event, and your application can register the same event when it needs to invoke mine, and Brew will handle the string-to-event code mechanism.
A word about the event arguments is in order. Because one of the event arguments is a thirty-two-bit integer, it's very tempting to overload this integer and use it as a pointer, as Brew does with many events such as EVT_APP_MESSAGE. As I write this, this actually worksan application can use ISHELL_SendEvent to send an event and a pointer to its private data to another application, and another application can accept the integer, cast it to a pointer of the appropriate type, and dereference the pointer in the first application's heap. This is a particularly nasty solution to passing large quantities of data between two applications for at least three reasons:
- There is no type safety in this transaction. If the sending or receiving application mis-casts the pointer, the data will not be interpreted correctly and one or more applications may crash as a result.
- Qualcomm has indicated that in future versions of Brew, each application will run in its own memory space, so that applications cannot share pointers to the same data.
- There are bettter ways to do it, which is what the rest of this article is about.
For these reasons, I strongly recommend using one of the following means to pass anything more than a sixteen or thirty-two bit integer between two applications.