The internal workings of the Delphi Android service

Every Delphi Android Service uses the FMX jar.

In the FMX jar, there exists several helper classes, such as ProxyInterface, ProxyService, etc.

When an Android Service project is created, a Java class is created with the same name as the project. So if you named your project MyAndroidServiceProject, you'll have a Java class created by the IDE, and named MyAndroidServiceProject. This class inherits (or extends) the Service class. And in addition, (from the FMX jar) the ProxyService class has a static initializer that loads the libProxyAndroidService.so library from the native library directory. The ProxyAndroidService library exports these routines:

  • Java_com_embarcadero_rtl_ProxyService_onCreateNative
  • Java_com_embarcadero_rtl_ProxyService_onDestroyNative
  • Java_com_embarcadero_rtl_ProxyService_onStartCommandNative
  • Java_com_embarcadero_rtl_ProxyService_onBindNative
  • Java_com_embarcadero_rtl_ProxyService_onUnbindNative
  • Java_com_embarcadero_rtl_ProxyService_onRebindNative
  • Java_com_embarcadero_rtl_ProxyService_onTaskRemovedNative
  • Java_com_embarcadero_rtl_ProxyService_onConfiguratedChangedNative
  • Java_com_embarcadero_rtl_ProxyService_onLowMemoryNative
  • Java_com_embarcadero_rtl_ProxyService_onHandleIntentNative
  • Java_com_embarcadero_rtl_ProxyService_GetDelphiService
  • Java_com_embarcadero_rtl_ProxyService_onHandleMessageNative

The System.Android.ServiceApplication unit exports the following routines:

  •   OnCreateDelphi
  •   OnDestroyDelphi
  •   OnStartCommandDelphi
  •   OnBindDelphi
  •   OnUnbindDelphi
  •   OnRebindDelphi
  •   OnTaskRemovedDelphi
  •   OnConfigurationChangedDelphi
  •   OnLowMemoryDelphi
  •   OnTrimMemoryDelphi
  •   OnHandleIntentDelphi
  •   OnHandleMessageDelphi
  •   getDelphiService

Each of the Java_com_embarcadero_rtl_ProxyService_* routines declared in the ProxyService class are declared as a private static native routine with its corresponding parameters. In addition, they are also declared as a public static void routine (without the "Native" suffix), so when MyAndroidService.onCreate routine is called, it calls the ProxyService's onCreate, which in turn calls the private static onCreateNative (which is Java_com_embarcadero_rtl_ProxyService_onDestroyNative, declared in com.embarcadero.ProxyService, located in FMX.jar), which then calls the exported onCreateDelphi routine. Graphically, this looks like:

MyAndroidServiceProject.onCreate (libMyAndroidServiceProject.so) -> ProxyService.onCreate (FMX.jar) -> ProxyService.onCreateNative (FMX.jar / libProxyAndroidService.so) -> MyAndroidServiceProject.onCreateDelphi (libMyAndroidServiceProject.so) -> SystemEntry  -> TAndroidServiceCallbacks.OnCreateCallback -> TYourDataModule.OnCreate

One thing that the onCreateDelphi routine does differently from the other onXXXXDelphi routines is that it calls an internal method named SystemEntry. The SystemEntry routine is responsible to setup the System.JavaMachine, and System.JavaContext variables, then call the exported _NativeMain routine which is the entry point to where your project begins.  SystemEntry calls Application.Initialize, Application.CreateForm(TDM, DM), and Application.Run. Application.CreateForm sets up TAndroidServiceCallbacks, so that it links to TYourDataModule's onXXXX events.

Due to the way it's designed, after creating an Android Service, you'll need to add the Android Service to a Multi Device application.

Published Sun, 25 Jun 2017 @ 4:56 PM by chuacw
Related articles: ,