44

In my android project, I have ImageAdapter class in which I pass app context for some further needs.

public class ImageAdapter extends BaseAdapter {
    private Context c;

    public ImageAdapter(Context c) {
            this.c = c;
    }
    ...
}

The problem is that I wanna make ImageAdapter as a singleton to have an easy access to the instance of this class from all of my activities. But I have no idea how to pass app context from getApplicationContext() method from one of my activities to ImageAdapter. So is there any "magic" to do that as follows?

public class ImageAdapter extends BaseAdapter {

    private Context c;

    private static class Holder {
            public static final ImageAdapter IA = new ImageAdapter();
    }

    private ImageAdapter() {
            this.c = /* some magic here */.getApplicationContext();
    }

    public static ImageAdapter getInstance() {
            return Holder.IA;
    }
    ...
}

Maybe you have some other ideas for sharing ImageAdapter for any of my activities. I'm a newbie to android and I'm a little bit confused with the ways of passing data among activities.

I will be grateful for any help.

Ram Koti
  • 2,203
  • 7
  • 26
  • 36
Dmitry
  • 670
  • 1
  • 6
  • 11
  • 1
    you stated in your question that "I wanna make ImageAdapter as singleton to have an easy access to the instance of this class from all of my activities." how can you access easily instance of imageadapter class and use all of you activities, please elaborate I wanna increase my knowledge about it – blackHawk Aug 07 '17 at 13:58

3 Answers3

95

Update: 06-Mar-18

Use MyApplication instance instead of Context instance. Application instance is a singleton context instance itself.

public class MyApplication extends Application {

    private static MyApplication mContext;

    @Override
    public void onCreate() {
        super.onCreate();
        mContext = this;
    }

    public static MyApplication getContext() {
        return mContext;
    }
}

Previous Answer

You can get the the application context like this:

public class MyApplication extends Application {

    private static Context mContext;

    @Override
    public void onCreate() {
        super.onCreate();
        mContext = getApplicationContext();
    }

    public static Context getContext() {
        return mContext;
    }
}

Then, you can call the application context from the method MyApplication.getContext()

Don't forget to declare the application in your manifest file:

<application
    android:name=".MyApplication"
    android:icon="@drawable/icon"
    android:label="@string/app_name" >
ARiF
  • 1,079
  • 10
  • 23
mohammed momn
  • 3,230
  • 1
  • 20
  • 16
  • 5
    BTW, the Application *is* the application context; `getApplicationContext()` can be replaced by `this`. (`getApplicationContext` exists so that one can get to the application if you have *any* context.) Nothing wrong with the code, just pointing this out. – ToolmakerSteve Oct 08 '15 at 02:57
  • 8
    It is not advisable to put Android context classes in static fields. A static field will leak contexts -- Android Studio also warns about this issue. – netpork Sep 21 '16 at 10:46
  • 6
    Is this answer still up-to-date? Because the compiler says "Do not place Android context classes in static fields; this is a memory leak (and also breaks Instant Run) – Jim Clermonts Dec 23 '16 at 14:13
  • 3
    @JimClermonts I know the answer have been updated since you asked the question, but the updated answer should not give any warnings. The difference is that `Context` could be any context, including activities (that are destroyed now and then). By specifying it is the `Application` object (that lives as long as the app lives) there shouldn't be any problems – Anigif Jun 13 '18 at 08:53
  • are this still actual ? – Peter Jul 03 '18 at 13:22
7

I'd rather pass a context instance as a parameter to every method in singleton which really needs it

Micik
  • 130
  • 4
  • 1
    No way, I need context in overrided method @Override public View getView(int position, View convertView, ViewGroup parent) As I know it fires automatically. – Dmitry Feb 17 '14 at 01:02
3

APPROACH #1:

Since you specify that ImageAdapter is a singleton, one simple answer is to create that singleton from a class that has access to app context:

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        ImageAdapter.createIt(this);
    }
}

public class ImageAdapter extends BaseAdapter {
    private static ImageAdapter it;
    // Get the singleton.
    public static ImageAdapter getIt() {
        return it;
    }
    // Call this once, to create the singleton.
    public static void createIt(Context context) {
        it = new ImageAdapter(context);
    }

    private final Context c;
    private ImageAdapter(Context context) {
        c = context;
    }
}

APPROACH #2:

If it were not a singleton, then I would use the accepted answer. In that case, remove the local variable from ImageAdapter, because context can always be obtained from MyApplication. Expanding on the accepted answer, if you want a local method as a convenience, define ImageAdapter.getContext(). Complete solution:

public class MyApplication extends Application {
    private static Context appContext;
    public static Context getContext() {
        return appContext;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        appContext = this;
    }
}

public class ImageAdapter extends BaseAdapter {
    public ImageAdapter() {
    }

    // [Optional] Call this whenever you want the app context.
    private Context getContext() {
        return MyApplication.getContext();
    }
}
ToolmakerSteve
  • 18,547
  • 14
  • 94
  • 196