Java – Whether it is safe to pass context to non-context classes in this way

Whether it is safe to pass context to non-context classes in this way… here is a solution to the problem.

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();

Related Problems and Solutions