This is chapter 2 of our series Mastering Android Context. We will cover types of Context present in Android and which one to use when. If you have not read Chapter 1, we recommend to spend 5 minutes understanding what is a Context.
In Chapter 1. we agreed on Context is the bridge between components. We use it to communicate between components, instantiate components and access components.
Type of Context
There are many many ways you can get hold on context(
bad design spotted). Most of time we use one of the following when we need context.
- Application instance as context - Activity - Instance of your activity (this) - getApplicationContext() in Activity - getBaseContext() in Activity - Fragment - getContext() in Fragment - View - getContext() in View - Broadcast Receiver - Context received in broadcast receiver - Service - Instance of your service (this) - getApplicationContext() in Service - Context - getApplicationContext() in Context instance
Lets call these ways n-ways and we will use word “n-ways” in article when we want to refer these.
Yes there are other ways as well but more or less these are ways we use in our day to day development. Yes it is overwhelming! Don’t worry, we will explain the difference between these so we can use the right context at right place.
First, let’s see class heirarchy of Context and n-ways will make little sense.
To your surprise Context is an abstract class and there is only one concrete implementation of that which is ContextWrapper (
bad design spotted). This class hierarchy is the reason n-ways can be used when you need context. Good or bad, this is Android way, lets try to explain in my way.
I divide context into two categories. UI-Context and Non-UI Context context. This distinction will help you understanding n-ways little better.
In reality, only ContextThemeWrapper(see class hierarchy above) is UI-Context which means Context + Your theme.
Activity extends ContextThemeWrapper and that is the reason when you inflate any xml, your views are themed. If you will inflate your layout with Non-UI context, your layout will not be themed. Go ahead, try it.
So when you use activity as context, you are guaranteed using UI-Context. If you are using getContext from Fragment, indirectly you are using Activity(If you attached fragment via fragmentManager in activity).
But view.getContext() is not guaranteed to be UI-Context. Reason for that is it depends how View was instantiated. If it was instantiated using Layout Inflater and passed UI-Context, you get UI-Context back but if it was instantiated by not passing UI-Context, you get the other context back. For example, you can use Non-UI context with layout inflator OR you can construct View object directly using constructor with a Non-UI context, in that case you will get Non-UI context back. So be careful.
UI Context - Activity - Instance of your activity (this) - Fragment - getContext() in Fragment - View - getContext() in View (if View was constructed using UI-Context)
Anything except UI context is Non UI Context. Technically, anything which is not ContextThemeWrapper is Non-UI Context.
Non-UI Context is allowed do almost everything UI-Context can do(
bad design spotted). But as we pointed earlier, you lose theming. We said almost because one example is when you need Window access from context, Non-UI context can not provide. We will discuss this in detail in later chapter.
Non-UI Context - Application instance as context - Activity - getApplicationContext() in Activity - Broadcast Receiver - Context received in broadcast receiver - Service - Instance of your service (this) - getApplicationContext() in Service - Context - getApplicationContext() in Context instance
So where do we use Non-UI Context? As I recall from chapter 1, context is mainly used to communicate between components, instantiate components and access components. Non-UI Context can be used to communicate(*next chapter), instantiate components(*next chapter) and access components like resources.
Tip: Among n-ways all context type are supposed to be short lived except Application context, the one which you get from your application class OR using getApplicationContext() method when you have context access.
We have simplified little bit by putting Context in two buckets. UI Context is Context + Theming, technically any class which is subclass of ContextThemeWrapper comes in this bucker. Non-UI Context is all type of Context but UI. Even though there are many ways to access context object, there are small small differences few of which we have covered. We will learn where to use which Context in next chapter.