Context and memory leaks in AndroidManaging Context and avoiding Memory LeaksJuan RinconadaBlockedUnblockFollowFollowingJun 4Sooner or later every Android developer must face the concept of Context.
Toasts, Adapters, Intents, Inflaters, SharedPreferences, SystemServices are terms often associated with the Context.
Showing a Toast, opening a new screen, creating a view or saving data in preferences are all actions that require the use of Context as an argument.
Sometimes the solution is simple (like using this if we are inside an Activity), but other times we are not sure of what we are doing, and we are left wondering…What is the Context?An interface to the application environment.
Well… OK… but what does that mean…What that definition is trying to tell us is that the Context is a class with methods to access application resources and system services.
To get the Context, we normally use the Activity, writing the word this, for that, we can infer that an Activity is a Context.
And indeed, Activity, Service or Application are concrete implementations of the Context abstract class.
Inside an app there can be a some Activities, some Services, and therefore, more than one Context, but there is only one Application and, therefore, only one Application Context.
Complete inheritance treeWhat is the Context for?The most common scenarios when we need to use the Context is when using views (Toasts, Adapters, Inflaters), launching Activities (Intents) or accessing system services (SharedPreferences, ContentProviders).
If we are looking for a more formal classification, there are four scenarios:Gather app resources: res, assets, internal storageCommunication between Activities: IntentsAccess system services: SystemServicesGet App information: ApplicationInfoWhere do I get the Context from?There are three methods that return a Context, they are in views, activities and the ContextWrapper class, and every one of them has its function.
In a viewThe View class has the getContext() method to get the Context of the Activity that contains it.
Being an Activity Context and not an Application Context, it can have information about specific themes that change the aesthetics of that particular activity.
Because of this, the Activity Context is the one to go when managing views, inflating layouts, launching activities, showing dialogs or using short-term classes.
Understanding “short-term class” as: classLifespan <= activityLifespanIn an activityThe Activity class is a Context by inheritance.
This is the Activity Context mentioned earlier, we can access it using this.
But you probably already knew that.
The method you can use to get a different Context is getApplicationContext(), that, as the name implies, returns the application’s context, not the activity’s.
This is the Context of the process where activities run and it is used in classes that exceed the lifespan of the Activity, such as background tasks or data access.
In ContextWrapperThis is an intermediary class in the inheritance tree and provides the getBaseContext() method.
Its use is not recommended for most purposes.
Summing up…How to use every type of ContextIn this table we there are combinations between actions and types of Context.
It is important to point out the NO in the Application and Service columns when starting an Activity.
This is because the call stack is lost (1).
Also is not good to use it when inflating layouts, because they themes are applied to match the particular visual style of the Activity they are in (2).
Learning to properly manage the Context is an skill that will save us from unexpected problems and that is closely linked with memory leakage.
Memory LeaksThe main objective of this article is helping you prevent memory leaks.
This is: not releasing RAM resources when no longer needed.
If this is done several times, the part of memory assigned to the application may be exceeded causing the system to terminate the execution and the user to experience an app crash.
Common causes of memory leaks are static variables, Singleton pattern, background tasks and anonymous inner classes.
Let’s see some examples on how to detect and fix them.
Static variableIn the new example the static variable vista has a reference to the activity’s context:If the application keeps running after the Activity is destroyed, the memory it is using is not freed because the vista variable has a reference to the context of that activity.
One solution is to dereference the variable inside the onDestroy() method.
The same problem can happen if, when using a Singleton, it is saving the Activity Context.
Usually the best solution, in that case, is to use the application context since we are supposed to have a proper MVC architecture, so no access to the views directly and no need for the activity context.
Inner classThe dreaded Inner Classes are the ones that are created inside another class or method.
If we do this inside, for example, an Activity, the inner class will hold a reference to the context of that activity:It is the same problem as before, really, the innerClass variable is static.
If it were dynamic the problem disappears (bye bye static):Object innerClass;Background taskAn asynchronous task can access an activity an keep running in the background after the activity is finished.
In this code, for example an AsyncTask is created inside an activity:The problem is, again, that we are creating a anonymous class.
If we put the same code inside a class inheriting AsyncTask the problem is gone.
To run MiAsyncTask:new MiAsyncTask.
execute();A Thread can lead to the same mistake, but with this time we can interrupt the thread when the activity is destroyed:Event handlingAnother delicate situation that can end up with a memory leak is when an activity is registered as a listener to handle events of a system service.
An example of this with a sensor:Solution is simple, cancel the registration:Memory leak detectionLeak Canary logoSometimes a tool is the fastest way to detect a memory leak, specially if we are dealing with a large project that has already a lot of code written.
Two fundamental tool are Memory Profiler and Leak Canary:Memory Profiler: This tool is part of Android Studio and it is the fastest way to generate a garbage collection and a file showing information about memory consumption.
Leak Canary: A miner’s canary for Android.
Installing this library inside our app we can see a trace of all the reference that lead to a memory leak in the device.
ReferenceIn-depth explanation of Context: https://possiblemobile.
com/2013/06/context/Article about Memory Leaks: https://android.
eu/9-ways-to-avoid-memory-leaks-in-android-b6d81648e35eSome videos about possible causes and solutions to memory leaks: https://www.
com/watch?v=DikbJw2D5RYMemory Profiler official documentation: https://developer.
com/studio/profile/memory-profiler?hl=es-419Leak Canary library: https://github.