com4j Event Handling
This document explains how you can subscribe to COM events.
Event Interface Definition
To subscribe to COM events, you first need an interface that defines the IID of the event interface, plus event methods that you'd like to subscribe, such as this:
@IID("{5846EB78-317E-4B6F-B0C3-11EE8C8FEEF2}")
public interface _IiTunesEvents {
/**
* Fired when a database change occurs.
*/
@DISPID(1)
void onDatabaseChangedEvent(Object deletedObjectIDs, Object changedObjectIDs);
/**
* Fired when a track has started playing.
*/
@DISPID(2)
void onPlayerPlayEvent(Object iTrack);
}
An event interface does not have to list all the event methods; if you omit some methods, those events
will be simply ignored. Also, technically the event interface can be a class — the only thing
required is the @IID
annotation and @DISPID
that designates which are event methods.
To make it easy to subscribe to COM events, tlbimp generate a class with empty methods. But you can also choose to write it manually.
Subscribe/Unsubscribe to events
You can subscribe to a COM object by using the following code:
Com4jObject comObject = ...; // more likely it's an interface derived from Com4jObject
EventCookie cookie = comObject.advise(_IiTunesEvents.class, new MyEventReceiver());
...
cookie.close(); // terminate subscription
Because of the reference counting in COM, you must explicitly perform unsubscription
by using the close
method, or otherwise both COM and Java objects will leak.
Event and Thread
If your thread X invokes a COM method, which in turn fires an event Y, then the thread that executes the event method Y will not be X, but a thread that com4j maintains internally. So the acess to thread local resources need to be done carefully. But note that there's no need of synchronization --- thread X blocks until your event code returns.
For some other kinds of events (such as iTunes playerStart/playerStop events), they happen without you calling into COM first. Those events are delivered in truly asynchronous ways, so you will need synchronization.