Статический способ получить «Контекст» в Android? - PullRequest
899 голосов
/ 05 января 2010

Есть ли способ получить текущий экземпляр Context внутри статического метода?

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

Ответы [ 19 ]

3 голосов
/ 13 декабря 2016

Согласно этому источнику вы можете получить свой собственный контекст, расширив ContextWrapper

public class SomeClass extends ContextWrapper {

    public SomeClass(Context base) {
      super(base);
    }

    public void someMethod() {
        // notice how I can use "this" for Context
        // this works because this class has it's own Context just like an Activity or Service
        startActivity(this, SomeRealActivity.class);

        //would require context too
        File cacheDir = getCacheDir();
    }
}

JavaDoc для ContextWrapper

Прокси-реализация контекста, которая просто делегирует все свои вызовы другому контексту. Может быть разделено на подклассы для изменения поведения без изменения исходного контекста.

3 голосов
/ 18 августа 2011

Я думаю, вам нужно тело для getAppContext() метода:

public static Context getAppContext()
   return MyApplication.context; 
3 голосов
/ 06 апреля 2013

Вы можете использовать следующее:

MainActivity.this.getApplicationContext();

MainActivity.java:

...
public class MainActivity ... {
    static MainActivity ma;
...
    public void onCreate(Bundle b) {
         super...
         ma=this;
         ...

Любой другой класс:

public ...
    public ANY_METHOD... {
         Context c = MainActivity.ma.getApplicationContext();
2 голосов
/ 30 декабря 2014

Я использую вариант шаблона проектирования Singleton, чтобы помочь мне в этом.

import android.app.Activity;
import android.content.Context;

public class ApplicationContextSingleton {
    private static Activity gContext;

    public static void setContext( Activity activity) {
        gContext = activity;
    }

    public static Activity getActivity() {
        return gContext;
    }

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

Затем я вызываю ApplicationContextSingleton.setContext( this ); в моей activity.onCreate () и ApplicationContextSingleton.setContext( null ); в onDestroy () ;

2 голосов
/ 15 марта 2018

Если вы не хотите изменять файл манифеста, вы можете вручную сохранить контекст в статической переменной в вашей начальной активности:

public class App {
    private static Context context;

    public static void setContext(Context cntxt) {
        context = cntxt;
    }

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

И просто установите контекст, когда ваша деятельность (или действия) начинаются:

// MainActivity

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Set Context
    App.setContext(getApplicationContext());

    // Other stuff
}

Примечание: Как и все другие ответы, это потенциальная утечка памяти.

1 голос
/ 12 июля 2018

Ответ Рохита кажется правильным. Однако следует помнить, что «Instant Run» в AndroidStudio зависит от того, насколько я знаю, что в вашем коде нет атрибутов static Context.

1 голос
/ 07 июля 2017

Итак, я изменил принятый ответ, потому что он вызывает утечку памяти, вот что я придумал ...

AndroidManifest.xml

    <application android:name="com.xyz.MyApplication">
...

    </application>

MyApplication.java

public class MyBakingAppContext extends Application {
    private static Object mContext;

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

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

Что я на самом деле сделал, так это назначил контекст объекту и вернул объект как контекст (приведение его к контексту). Надеюсь, это поможет.

1 голос
/ 23 февраля 2016

Если по какой-то причине вам нужен контекст приложения в любом классе, а не только в тех, которые расширяют приложение / активность, возможно, для некоторых фабричных или вспомогательных классов.Вы можете добавить следующий синглтон в ваше приложение.

public class GlobalAppContextSingleton {
    private static GlobalAppContextSingleton mInstance;
    private Context context;

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

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

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

    public Context getApplicationContext() {
        return context;
    }
}

, а затем инициализировать его в onCreate класса приложения с помощью

GlobalAppContextSingleton.getInstance().initialize(this);

, использовать его где угодно, вызывая

GlobalAppContextSingleton.getInstance().getApplicationContext()

Однако я не рекомендую этот подход ни к чему, кроме контекста приложения.Как это может вызвать утечки памяти.

1 голос
/ 26 февраля 2013

Я только что выпустил jQuery-фреймворк для Android под названием Vapor API , цель которого - упростить разработку приложений.

Центральный $ класс фасадов поддерживает WeakReference (ссылка на потрясающий пост в блоге Java об этом Ethan Nicholas) в текущем контексте Activity, который вы можете получить по телефону:

$.act()

A WeakReference поддерживает ссылку, не предотвращая сборку мусора, возвращая исходный объект, поэтому у вас не должно быть проблем с утечками памяти.

Недостатком, конечно, является то, что вы рискуете, что $.act() может вернуть ноль. Я еще не сталкивался с этим сценарием, так что, возможно, это просто минимальный риск, о котором стоит упомянуть.

Вы также можете установить контекст вручную, если вы не используете VaporActivity в качестве Activity класса:

$.act(Activity);

Кроме того, большая часть инфраструктуры Vapor API использует этот хранимый контекст по своей сути, что может означать, что вам вообще не нужно хранить его самостоятельно, если вы решите использовать среду. Посетите сайт для получения дополнительной информации и образцов.

Надеюсь, это поможет:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...