Whether it is safe to pass context to non-context classes in this way
I’ve read several articles about passing context to adapters or something, and I’ve made some kind of context holder to get the application context:
import android.content.Context;
public class ContextHolder {
private static ContextHolder ourInstance = new ContextHolder();
private Context context;
public static ContextHolder getInstance() {
return ourInstance;
}
private ContextHolder() {
context = null;
}
public void setContext(Context context){
this.context = context;
}
public Context getApplicationContext(){
return context;
}
}
Then create a ContextHolder object in MainActivity and set the context like this:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ContextHolder contextHolder = ContextHolder.getInstance();
contextHolder.setContext(this.getApplicationContext());
}
In some other classes, I need to use contex:
ContextHolder contextHolder = ContextHolder.getInstance();
Resources resources = contextHolder.getApplicationContext().getResources();
The question is, am I doing it right?
Does it cause memory leaks or other annoying things?
Solution
in MainActivity i`m creating ContextHolder
But for what? Activity is already a subclass of Context:
java.lang.Object
↳ android.content.Context
↳ android.content.ContextWrapper
↳ android.view.ContextThemeWrapper
↳ android.app.Activity
So you can just use this (or
MainActivity.this
). Not to mention the contextHolder
variable, you put the holder object in the displayed code is locally scoped and only visible in onCreate().
Can it cause memory leaks or other nasty stuff?
I recommend using LeakCanary to catch all memory leaks in your code. See: https://github.com/square/leakcanary
In some other class, where i need to use contex:
ContextHolder contextHolder = ContextHolder.getInstance();
Resources resources = contextHolder.getApplicationContext().getResources();
This is all unnecessary and over-engineered. If you only need to get the application context, subclass Application
class:
class MyApplication extends Application {
protected static Context mContext;
@Override
public void onCreate() {
super.onCreate();
mContext = this;
}
public static Context getAppContext() {
return mContext;
}
}
Set it to your application class in list:
<application
android:name=". MyApplication"
...
Then whenever you need context that you can’t get otherwise, just call:
MyApplication.getAppContext();