Лучший способ получить контекст приложения в статическом методе в Android

Я работаю над приложением для Android, которое имеет несколько действий. В нем у меня есть класс с несколькими статическими методами. Я хотел бы иметь возможность вызывать эти методы из разных действий. Я использую статические методы для загрузки данных из XML-файла через XmlResourceParser. Для создания XmlResourceParser требуется вызов контекста приложения. Итак, мой вопрос: как лучше всего получить ссылку на контекст приложения в статические методы? Каждое действие получило его и передало? Сохранить как-то в глобальной переменной?


person Slapout    schedule 07.05.2010    source источник
comment
Возможный дубликат Статический способ получить «Контекст» на Android?   -  person Robby Cornelissen    schedule 26.07.2016


Ответы (4)


Лучшим способом было бы передать объект Activity в качестве параметра статическим функциям.

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

person Karan    schedule 07.05.2010

Я не уверен, что это будет работать все время, но сейчас это работает для меня:

public class myActivity extends ListActivity
{
    public static Context baseContext;

    public void onCreate(Bundle savedInstanceState) 
    {
        baseContext = getBaseContext();
    }

Затем вы можете использовать статику в своем пакете:

myApplication.baseContext
person gjpc    schedule 28.10.2010
comment
Просто будьте готовы найти значение baseContext null из статических контекстов, которые запускаются до вызова нестатического метода OnCreate. - person Melinda Green; 19.10.2011
comment
Такой подход приведет к утечкам памяти в вашем коде. Не делай этого! - person jpardogo; 02.09.2014
comment
@jpardogo множественные утечки памяти ?? как? - person gjpc; 04.09.2014
comment
У вас есть полное объяснение того, почему вы не можете сделать статическую ссылку на контекст активности здесь: goo.gl/rxz5df и здесь goo.gl/1PauC - person jpardogo; 04.09.2014
comment
этот подход создает утечку памяти, задаваясь вопросом, кто проголосовал - person blackHawk; 07.08.2017
comment
Если вы собираетесь использовать статическое поле для хранения контекста, используйте контекст приложения, а не контексты действий. - person sisisisi; 27.11.2018

Это должно дать вам доступ к applicationContext из любого места, что позволит вам получить applicationContext из любого места, где его можно использовать; Toast, getString(), sharedPreferences и т. д. Я использовал это, чтобы несколько раз получить applicationContext внутри статических методов.

Синглтон:

package com.domain.packagename;

import android.content.Context;

/**
 * Created by Versa on 10.09.15.
 */
public class ApplicationContextSingleton {
    private static PrefsContextSingleton mInstance;
    private Context context;

    public static ApplicationContextSingleton getInstance() {
        if (mInstance == null) mInstance = getSync();
        return mInstance;
    }

    private static synchronized ApplicationContextSingleton getSync() {
        if (mInstance == null) mInstance = new PrefsContextSingleton();
        return mInstance;
    }

    public void initialize(Context context) {
        this.context = context;
    }

    public Context getApplicationContext() {
        return context;
    }

}

Инициализируйте Singleton в вашем подклассе Application:

package com.domain.packagename;

import android.app.Application;

/**
 * Created by Versa on 25.08.15.
 */
public class mApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        ApplicationContextSingleton.getInstance().initialize(this);
    }
}

Если я не ошибаюсь, это дает вам доступ к applicationContext везде, вызывайте его с помощью ApplicationContextSingleton.getInstance.getApplicationContext(); Вам не нужно очищать это в любой момент, так как когда приложение закрывается, это все равно происходит.

Не забудьте обновить AndroidManifest.xml, чтобы использовать этот подкласс Application:

<?xml version="1.0" encoding="utf-8"?>

<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.domain.packagename"
    >

<application
    android:allowBackup="true"
    android:name=".mApplication" <!-- This is the important line -->
    android:label="@string/app_name"
    android:theme="@style/AppTheme"
    android:icon="@drawable/app_icon"
    >

Пожалуйста, дайте мне знать, если вы видите что-то не так, спасибо. :)

person Versa    schedule 25.09.2015
comment
Я не знаю, является ли этот способ лучшим способом сделать это. Но я думаю, что инициализация синглетонов, которым нужен контекст при входе в Application, является хорошей идеей. Если нет, я должен передавать Context в SingletonClass.getInstance(Context) каждый раз, когда я его вызываю, и это действительно раздражает. - person ProtossShuttle; 28.09.2015
comment
Да, это немного раздражает, я использовал такие классы, как эти gPrefs < href="https://gist.github.com/kai-kb/3da8389513c21a671dbe" rel="nofollow noreferrer">gString, чтобы в некоторой степени бороться с этим. - person Versa; 29.09.2015
comment
Этот подход также генерирует предупреждение об утечке и проблемах с мгновенным запуском: не размещайте классы контекста Android в статических полях (статическая ссылка на ApplicationContextSingleton, контекст поля которого указывает на контекст); это утечка памяти (а также прерывает Instant Run). Статическое поле приведет к утечке контекста. - person WilliamK; 10.02.2017
comment
@WilliamK Я не думаю, что контекст приложения может когда-либо просочиться, поскольку все приложение уничтожается, когда приложение теряется. То, что он прерывает мгновенный запуск, немного беспокоит, и я думаю, его нельзя назвать перспективным, поскольку в какой-то момент Application может перестать быть божественным объектом. - person Versa; 10.02.2017
comment
@WilliamK Измените Context на Application в типе поля, чтобы удалить это предупреждение. - person Thomas; 18.01.2021

В блоге Sane Tricks For InsaneWorld есть сообщение с ответом. В нем говорится, что вы можете заменить объект приложения своим собственным подклассом, а затем статически сохранить контекст приложения. Вы можете найти пример кода в сообщении.

Исходный пост в блоге — http://uquery.blogspot.co.il/2011/08/how-to-get-application-context.html

person Tom Susel    schedule 13.04.2013
comment
Начиная с Android Studio 2.2.2, этот подход генерирует предупреждение: не размещайте классы контекста Android в статических полях; это утечка памяти (а также прерывает Instant Run). Статическое поле приведет к утечке контекста. - person WilliamK; 10.02.2017
comment
@WilliamK есть исключение из этого правила в контексте приложения. Он живет до тех пор, пока живет ваше приложение, поэтому он не может утечь. Однако не помещайте контекст действия в статическое поле! - person JensV; 13.02.2018