The Context
class of the Android framework is used to retrieve application-specific resources.
The class is also used for performing application-level operations such as starting activities and broadcasting.
A Context
class in Android is retrieved using either getContext()
or getApplicationContext()
function.
The getContext()
method is available from the View
class. It’s used to return the context of the view. Usually, it’s the current Activity
class.
The getApplicationContext()
method is available from the Activity
class, used to return the application context.
When you define a context field as static, Android will respond with the following warning:
Do not place Android context classes in static fields;
this is a memory leak
Here’s an Android Activity
class that causes the above warning:
public class MainActivity extends AppCompatActivity {
private static Context ctx;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ctx = getApplicationContext();
setContentView(R.layout.activity_main);
Button btn = findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
navigateActivity();
}
});
}
void navigateActivity() {
Intent in = new Intent(ctx, SecondActivity.class);
startActivity(in);
}
}
In the code above, you can see that a static reference to the Context
instance is created.
The ctx
is later assigned the context from getApplicationContext()
call inside the onCreate()
method.
Since a Context
is a global Application object, it’s going to always be available during the runtime of your app.
This is why you don’t need to create a static reference to the Context
class. You can always call the getApplicationContext()
from an Activity
class when needed.
You can remove the static context and change the code above as follows:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
navigateActivity();
}
});
}
void navigateActivity() {
Intent in = new Intent(getApplicationContext(), SecondActivity.class);
startActivity(in);
}
}
When you need a reference to the Context
class outside of an Activity
class, you can pass the Context
as a parameter to the method that requires it.
For example, suppose you have a static
method in MainActivity
class as shown below:
public static void greetings(Context ctx){
Toast.makeText(ctx, "Hello!", Toast.LENGTH_SHORT).show();
}
Because the greetings()
method above is static, you can’t call getApplicationContext()
inside the method body.
You can call it from the Activity
where you call the greetings()
method like this:
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
MainActivity.greetings(getApplicationContext());
}
});
}
}
In the code above, the MainActivity.greetings()
method is called from SecondActivity
class, with the context retrieved from getApplicationContext()
call.
This way, you can get the application Context
instance without creating a static reference to it.
And that’s how you solve the Do not place Android context classes in static fields
problem.
I hope this tutorial has been useful for you. 👍