Получить контекст приложения из одноэлементного класса без активности

В моем проекте Android у меня есть класс ImageAdapter, в котором я передаю контекст приложения для некоторых дальнейших нужд.

public class ImageAdapter extends BaseAdapter {
    private Context c;

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

Проблема в том, что я хочу сделать ImageAdapter как синглтон, чтобы иметь легкий доступ к экземпляру этого класса из всех моих действий. Но я понятия не имею, как передать контекст приложения из метода getApplicationContext() из одного из моих действий в ImageAdapter. Так есть ли какая-то «магия», чтобы сделать это следующим образом?

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;
    }
    ...
}

Может быть, у вас есть другие идеи по совместному использованию ImageAdapter для любых моих действий. Я новичок в Android, и меня немного смущают способы передачи данных между действиями.

Буду признателен за любую помощь.


person Dmitry    schedule 17.02.2014    source источник
comment
в своем вопросе вы заявили, что я хочу сделать ImageAdapter одноэлементным, чтобы иметь легкий доступ к экземпляру этого класса из всех моих действий. как вы можете легко получить доступ к экземпляру класса imageadapter и использовать все свои действия, пожалуйста, уточните, я хочу расширить свои знания об этом   -  person blackHawk    schedule 07.08.2017


Ответы (3)


Обновление: 06 марта 18

Используйте экземпляр MyApplication вместо экземпляра Context. Экземпляр Application сам по себе является экземпляром одноэлементного контекста.

public class MyApplication extends Application {

    private static MyApplication mContext;

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

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

Предыдущий ответ

Вы можете получить контекст приложения следующим образом:

public class MyApplication extends Application {

    private static Context mContext;

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

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

Затем вы можете вызвать контекст приложения из метода MyApplication.getContext()

Не забудьте объявить приложение в файле манифеста:

<application
    android:name=".MyApplication"
    android:icon="@drawable/icon"
    android:label="@string/app_name" >
person mohammed momn    schedule 17.02.2014
comment
Кстати, приложение является контекстом приложения; getApplicationContext() можно заменить на this. (getApplicationContext существует для того, чтобы можно было получить доступ к приложению, если у вас есть любой контекст.) Ничего плохого в коде, просто указываю на это. - person ToolmakerSteve; 08.10.2015
comment
Не рекомендуется размещать классы контекста Android в статических полях. Статическое поле приведет к утечке контекста — Android Studio также предупреждает об этой проблеме. - person netpork; 21.09.2016
comment
Этот ответ все еще актуален? Поскольку компилятор говорит: «Не размещайте классы контекста Android в статических полях; это утечка памяти (а также ломает Instant Run) - person Jim Clermonts; 23.12.2016
comment
@JimClermonts Я знаю, что ответ был обновлен с тех пор, как вы задали вопрос, но обновленный ответ не должен давать никаких предупреждений. Разница в том, что Context может быть любым контекстом, включая действия (которые время от времени уничтожаются). Указав, что это объект Application (который живет, пока живет приложение), проблем быть не должно. - person Anigif; 13.06.2018
comment
это еще актуально? - person Peter; 03.07.2018

Я бы предпочел передать экземпляр контекста в качестве параметра каждому методу в синглтоне, который действительно в нем нуждается.

person Micik    schedule 17.02.2014
comment
Ни в коем случае, мне нужен контекст в переопределенном методе @Override public View getView(int position, View convertView, ViewGroup parent) Как я знаю, он срабатывает автоматически. - person Dmitry; 17.02.2014

ПОДХОД №1:

Поскольку вы указываете, что ImageAdapter является синглтоном, один простой ответ — создать этот синглтон из класса, имеющего доступ к контексту приложения:

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;
    }
}

ПОДХОД № 2:

Если бы это был не синглтон, я бы использовал принятый ответ. В этом случае удалите локальную переменную из ImageAdapter, поскольку контекст всегда можно получить из MyApplication. Расширяя принятый ответ, если вам нужен локальный метод для удобства, определите ImageAdapter.getContext(). Полное решение:

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();
    }
}
person ToolmakerSteve    schedule 08.10.2015