This article aims to teach you what context.getSystemService
method is and how to use it wisely
Purpose
Context.getSystemService
method is used when we want to access one of few Android system-level services.
To name only few of managers that we can get:
LocationManager
– access GPS device informationNotificationManager
– manage (create, cancel) notificationsConnectivityManager
– access network connection details and manage those connectionsLayoutInflater
– inflate and create views from xml layout resource files
Full list of available managers could be found here
Every of those managers is a bridge to communicate and use system-level features from our application. Easiest way to illustrate those managers in connection with the whole android system, is to look a one of Google Android system architecture figures. As you can see there, system service – orange box lies in the middle and between application framework (software layer) and linux kernel (hardware layer)
How to use
Context object is the only necessary thing to get any of those services. Here are few examples
1 2 3 4 5 6 7 8 9 |
class MyCustomApplication : Activity() { override fun onCreate() { super.onCreate() val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager // code using location manager } } |
getSystemService usage in custom Application object
1 2 3 4 5 6 7 8 9 |
class MyCustomApplication : Application() { override fun onCreate() { super.onCreate() val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager // code using location manager } } |
getSystemService usage in custom Activity object
As you can see, to access one of those services we only need to call described method using Context
object instance and cast result of getSystemService
method.
It does not matter what type of context it its. It could be:
Activity
,Application
,Service
System services are cached per Context instance
Every service connection created and retrieved with getSystemService
method on specific context object is cached/reused.
What does it mean? If you call getSystemService(Context.LOCATION_SERVICE)
multiple times on same Activity object instance you will get same service object.
Let’s look at the example:
1 2 3 4 5 6 7 8 9 10 11 12 |
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val locationManager1 = getSystemService(Context.LOCATION_SERVICE) as LocationManager val locationManager2 = getSystemService(Context.LOCATION_SERVICE) as LocationManager val locationManager3 = getSystemService(Context.LOCATION_SERVICE) as LocationManager // code using location manager } } |
Every of those locationManager1
, locationManager2
, locationManager3
actually refers to the same object in the memory.
But when you use different contexts objects different services objects will be created:
1 2 3 4 5 6 7 8 9 10 11 12 |
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val locationManagerFromActivity = getSystemService(Context.LOCATION_SERVICE) as LocationManager val locationManagerFromApplication = applicationContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager // locationManagerFromActivity.equals(locationManagerFromActivity) is false } } |
locationManagerFromActivity
is not same object as locationManagerFromApplication
so you have to be careful on that!
What to remember while using getSystemService method
- System services are bridge between system libraries/hardware layer and your application
getSystemService
result object is cached per single Context instance- Use system service consistently from one Context to avoid potential problems
- For instance if you want to listen for location updates (with
LocationManager
) across multiple activities getLocationManager
service usingApplication
context - On the other hand if you want to use specific service only for short local task purpose use specific
Activity
orService
context. I. e. to getLayoutInflater
service object
- For instance if you want to listen for location updates (with
- System services objects like i.e.
LocationManager
internally holds reference toContext
instance with which they were created.- Do not hold globally (as singleton) instances of system services retrieved with local
Activity
instance context - You can hold safely system services only if they are created with global
Application
instance context. Remember to do it only if there is really important justification for that, because most of the time callinggetSystemService
fromActivity
instance context on demand will be good enough
- Do not hold globally (as singleton) instances of system services retrieved with local