-> A Service is an `application component` that can perform long-running operations in the background.
-> Additionally, a component can bind to a service to interact with it and even perform interprocess communication (IPC).
Inter-Process Communication or IPC in short, is a mechanism that allows multiple independent processes to communicate and exchange data.
1) Network Transactions
2) Play Music
3) Perform I/O operations
4) Interact with content providers
Service runs on 'Main Thread', avoid thread-blocking operations else it will produce ANR's.
ANR's are a problem because the app's main thread, can't process user input events or draw.
-> Input dispatching timed out:
* 5-sec time out
-> Executing service
* If a service declared by your app cannot finish executing Service.onCreate()
and Service.onStartCommand()/Service.onBind() within a few seconds.
-> Service.startForeground() not called
* If your app uses Context.startForegroundService() to start a new service in the foreground,
but the service then does not call startForeground() within 5 seconds.
-> Broadcast of intent
* If a BroadcastReceiver hasn't finished executing within a set amount of time.
If the app has any activity in the foreground, this timeout is 5 seconds.
Android shows ANR dialogs for apps that take too long to process the broadcast message only
if Show all ANRs is enabled in the device’s Developer options. For this reason, background ANR
dialogs are not always displayed to the user, but the app could still be experiencing performance issues.
-> Foreground Service (Noticeable to the user) e.g. Audio Player
-> Background Service (Hidden) e.g. Cleaning Storage
-> Bound Service (Binded with an application component)
> Bound service can be binded with multiple components. It will automatically be get killed when all components unbind it.
> A bound service runs only as long as another application component is bound to it.
> It can be binded with already running service. (music player {current song}) and stopSelf won't work, untill unbind.
IntentService
-> Extent to base class
-> It will not work well starting with Android 8 Oreo, due to the introduction of Background execution limits.
-> This class was deprecated in API level 30.
-> Use `JobIntentService` instead
JobIntentService
-> Also deprecated, use work Manager.
In many cases, using WorkManager is preferable to using foreground services directly.
<manifest ... >
...
<application ... >
<service android:name=".ExampleService" />
...
</application>
</manifest>
class HelloService : Service() {
...
}
1) onStartCommand()
This method will be triggered when 'startService()' is called. To top a service, call `stopSelf()` or `stopService()`
2) onBind()
This method will be triggered when 'bindService()' is called. It will stop service, once all components are unbouned.
You must always implement this method `IBinder`, however, if you don't want to allow binding, you should return null.
3) onCreate()
This method will be triggered when the service is initially created (before it calls either onStartCommand() or onBind()).
If the service is already running, this method is not called.
4) onDestroy()
The system invokes this method when the service is no longer used and is being destroyed. Your service should implement
this to clean up any resources such as threads, registered listeners, or receivers. This is the last call that the service receives.
-> Low memory
-> Cannot get killed if user is interacting to it's binded component
-> Foreground services are rarely get killed.
There are 3 return types in `onStartCommand()`
1) START_STICKY: (Will restart with null intent)
2) START_NOT_STICKY: (Will not restart) e.g. for alarm closing
3) START_REDELIVER_INTENT: (Will restart with previous intent)
After you publish your application, leave this name unchanged to avoid the risk of
breaking code due to dependence on explicit intents to start or bind the service.
startForeground()
This method creates a background service, but the method signals to the system
that the service will promote itself to the foreground. Once the service has been created,
the service must call its startForeground() method within five seconds. (OTHERWISE ANR)
startService()
The startService() method returns immediately, and the Android system
calls the service's onStartCommand() method. If the service isn't already running,
the system first calls onCreate(), and then it calls onStartCommand().
Result from Service
Client that starts the service can create a PendingIntent for a broadcast (with getBroadcast())
and deliver it to the service in the Intent that starts the service.
Foreground Service
Example: Music Player, Fitness App (Walking Distance)
1) The system waits 10 seconds before showing the notification associated with a foreground service
(**Android 12 or higher**)
It can be shown immediately in following cases
-> Action Buttons
-> ForegroundServiceType: `mediaPlayback`, `mediaProjection`, or `phoneCall`
-> Notification.Builder setForegroundServiceBehavior (int behavior)
2) Starting in Android 13 (API level 33), users can dismiss the notification associated with a foreground
service by default by swipe. For preventing this: set `true` to `setOngoing()` in `Notification.Builder`
3) Add permission. *Android 9 or higher must request) else **Security Exception**
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
Note: It's a normal permission
4) Notification must be or equal to PRIORITY_LOW
5) It can be called from background, except for few cases
e.g. FCM high priority, bubble, notification, widget, alarm, devices current input method, etc (13 points)
[https://developer.android.com/guide/components/foreground-services#background-start-restriction-exemptions]
6) To Stop a foreground, we can call stopForeground(parameter)
-> STOP_FOREGROUND_DETACH: Notification will remain after killing foreground service.
-> STOP_FOREGROUND_REMOVE: Notification will be removed as well.
7) To stop a service, we can call stopSelf()
It shows a list of apps that are currently running a foreground service.
This list is labeled Active apps. Next to each app is a Stop button.
<service
android:name=".services.foreground.MyForegroundService"
android:foregroundServiceType="location"
/>
Bound Service
"A bound service is the server in a client-server interface. It allows components (such as activities)
to bind to the service, send requests, receive responses, and perform interprocess communication (IPC).
-> It does not run in the background indefinitely.
-> It will remain until last component is bounded.
-> Beginning with Android 5.0 (API level 21), the system throws an exception if you call
bindService() with an implicit intent.
1) Extending the Binder class
2) Using a Messanger
3) Using AIDL
-> Local (Binder Class)
-> Remote (Messanger, AIDL)
-> Implement ServiceConnection (Your implementation must override two callback methods)
- onServiceConnected()
The system calls this to deliver the IBinder returned by the service's onBind() method.
- onServiceDisconnected()
The Android system calls this when the connection to the service is unexpectedly lost,
such as when the service has crashed or has been killed.
This is not called when the client unbinds.
unbindService()