Android Tutorial Starter Service - Consistent & Single Entry Point

Status
Not open for further replies.
One of the challenges that developers of any non-small Android app need to deal with, is the multiple possible entry points.

During development in almost all cases the application will start from the Main activity.
Many programs start with code similar to:
B4X:
Sub Activity_Create (FirstTime As Boolean)
If FirstTime Then
  SQL.Initialize(...)
  SomeBitmap = LoadBitmap(...)
  'additional code that loads application-wide resources
End If
End Sub

Everything seems to work fine during development. However the app "strangely" crashes from time to time on the end user device.
The reason for those crashes is that the OS can start the process from a different activity or service. For example if you use StartServiceAt and the OS kills the process while it is in the background.
Now the SQL object and the other resources will not be initialized.

Starting from B4A v5.20 there is a new feature named Starter service that provides a single and consistent entry point. If the Starter service exists then the process will always start from this service.

The Starter service will be created and started and only then the activity or service that were supposed to be started will start.
This means that the Starter service is the best place to initialize all the application-wide resources.
Other modules can safely access these resources.
The Starter service should be the default location for all the public process global variables. SQL objects, data read from files and bitmaps used by multiple activities should all be initialized in the Service_Create sub of the Starter service.

Notes

  • The Starter service is identified by its name. You can add a new service named Starter to an existing project and it will be the program entry point.
  • This is an optional feature. You can remove the Starter service.
  • You can call StopService(Me) in Service_Start if you don't want the service to keep on running. However this means that the service will not be able to handle events (for example you will not be able to use the asynchronous SQL methods).
  • The starter service should be excluded from compiled libraries. Its #ExcludeFromLibrary attribute is set to True by default.
  • The starter service should never be explicitly started. This means that if you want to start a service at boot then add a different service.
Android 8+ considerations
  • Starting from Android 8, the OS kills services while the app is in the foreground.
  • If you are using B4A v8.30+ then the starter service will not be killed until the whole process is killed.
  • You will see a message such as this one, 60 seconds after the app has moved to the background:
    ** Service (starter) Destroy (ignored)**
  • The above message means that the actual service is destroyed but the starter service is still available.
  • Don't make the starter service a foreground service. It will not work once the backed service is destroyed.
  • If you want to do a background task then you should add another service.
  • Related tutorial: Automatic Foreground Mode
 
Last edited:

Emme Developer

Well-Known Member
Licensed User
Longtime User
A simple curiosity, how this service is started before activity? Is it declared on manifest, or an event in application open for example? I ask this because i talk with a friend that works in android studio, and it uses ViewModel class to ensure a correct load of resource (that should not loaded in main activity create), but we don't have this problem because we inizialize all (where required) in staser service. This service make heavier application (in open event)? Thanks
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Is it declared on manifest
Yes.

As I wrote, under the hood the activity code starts the starter service and the code in B4A Activity_Create is called after the starter service is created.
Assuming that you are not doing too much work in Service_Create then the performance effect is minimal. You can also remove the starter service and it will not have any effect.
 

walterf25

Expert
Licensed User
Longtime User
One of the challenges that developers of any non-small Android app need to deal with, is the multiple possible entry points.

During development in almost all cases the application will start from the Main activity.
Many programs start with code similar to:
B4X:
Sub Activity_Create (FirstTime As Boolean)
If FirstTime Then
  SQL.Initialize(...)
  SomeBitmap = LoadBitmap(...)
  'additional code that loads application-wide resources
End If
End Sub

Everything seems to work fine during development. However the app "strangely" crashes from time to time on the end user device.
The reason for those crashes is that the OS can start the process from a different activity or service. For example if you use StartServiceAt and the OS kills the process while it is in the background.
Now the SQL object and the other resources will not be initialized.

Starting from B4A v5.20 there is a new feature named Starter service that provides a single and consistent entry point. If the Starter service exists then the process will always start from this service.

The Starter service will be created and started and only then the activity or service that were supposed to be started will start.
This means that the Starter service is the best place to initialize all the application-wide resources.
Other modules can safely access these resources.
The Starter service should be the default location for all the public process global variables. SQL objects, data read from files and bitmaps used by multiple activities should all be initialized in the Service_Create sub of the Starter service.

Notes

  • The Starter service is identified by its name. You can add a new service named Starter to an existing project and it will be the program entry point.
  • This is an optional feature. You can remove the Starter service.
  • You can call StopService(Me) in Service_Start if you don't want the service to keep on running. However this means that the service will not be able to handle events (for example you will not be able to use the asynchronous SQL methods).
  • The starter service should be excluded from compiled libraries. Its #ExcludeFromLibrary attribute is set to True by default.
  • The starter service should never be explicitly started. This means that if you want to start a service at boot then add a different service.
Can the Starter service be marked as a Sticky_Service?

Do i need to call StartServiceAt or will this service keep running even if the OS decides to kill it when it needs resources?

Thanks,
Walter
 

Peter Simpson

Expert
Licensed User
Longtime User
@trueboss323 Service_Create only runs the first time the service is created and does not run again, and Service_Start is ran every time the service is called. You can test this by adding lets say log("Service_Create") to Service_Create and Log("Service_Start") to Service_Start, you can see for yourself what happens...
 
Status
Not open for further replies.
Top