Native UltraLite for Java User's Guide
Understanding UltraLite Development
Adding ActiveSync synchronization to your application
The Native UltraLite for Java version of the CustDB sample allows synchronization through an application menu using a socket and through ActiveSync.
You can find source code for this sample in Samples\NativUltraLiteForJava\CustDB\Application.java under your SQL Anywhere directory. This section describes the code in that sample.
CustDB parses its arguments to check for a special flag used to indicate it was launched by the MobiLink provider for ActiveSync. This allows it to streamline initialization (such as avoiding form population), since applications launched for ActiveSync are expected to shut down once they have synchronized.
// Normal versus Active sync launch boolean isNormalLaunch = true; int alen = args.length; if( alen > 0 ) { String asflag = args[ alen - 1 ].toUpperCase(); if( asflag.compareTo( "ACTIVE_SYNC_LAUNCH" ) == 0) { isNormalLaunch = false; --alen; }
For normal launches (that is, non-ActiveSync launches), CustDB performs the connection initialization and determies the employee ID. It then initializes for ActiveSync by specifying a listener and loads its main form. For ActiveSync launches, CustDB performs the ActiveSync synchronization then shuts down.
if( isNormalLaunch ) { db.initActiveSync( "JULCustDB", main ); db.getOrder( 1 ); } else { // ActiveSync launch db.activeSync( false ); main.quit(); } public void initActiveSync( String appName, ActiveSyncListener listener ) { DEBUG( "initActiveSync" ); _conn.setActiveSyncListener( appName, listener ); } public void activeSync( boolean useDialog ) { try { // Change stream _conn.syncInfo.setStream( StreamType.ACTIVE_SYNC ); // since if "stream=" not in parms, //it defaults to tcpip, no // need to change stream parms _conn.synchronize( useDialog ); freeLists(); allocateLists(); skipToValidOrder(); } catch( SQLException e ) { System.out.println( "Can't synchronize, sql code=" + e.getErrorCode() ); } }
The class Application implements the ActiveSyncListener interface so the running application can be notified to perform an ActiveSync synchronization.
public class Application extends Frame implements ActionListener, // ActiveSyncListener functional only on CE devices ActiveSyncListener
When activeSyncInvoked() is invoked, it posts a message to the UI thread.
/** Define my own event class */ static final int ACTIVE_SYNC_EVENT_MASK = AWTEvent.RESERVED_ID_MAX + 1; static class ActiveSyncEvent extends AWTEvent { ActiveSyncEvent( Object source ) { super( source, ACTIVE_SYNC_EVENT_MASK ); } /** Process ActiveSync message */ public void activeSyncInvoked( boolean launchedByProvider ) { // This method is invoked on a special thread. // Post an event so that active sync // takes places on the same thread // as the rest of the application. DEBUG( "activeSyncInvoked()" ); getToolkit().getSystemEventQueue().postEvent( new ActiveSyncEvent( this ) ); DEBUG( "ActiveSync Event posted" ); }
The UI thread catches the message by overriding processEvent
/** Intercept my special action events * for ActiveSync */ protected void processEvent( AWTEvent e ) { if( e instanceof ActiveSyncEvent ) { _db.activeSync( true ); refresh(); } else { super.processEvent( e ); } }
However for the application to receive the event it must be enabled. This is done in Application's constructor.
// ActiveSync support enableEvents( ACTIVE_SYNC_EVENT_MASK );