Есть ли способ получить текущий Context
экземпляр внутри статического метода?
Я ищу этот путь, потому что ненавижу сохранять экземпляр Context каждый раз, когда он меняется.
android
android-context
Андреа Бакчега
источник
источник
Context
, тогда может быть лучший способ разработки кода.Ответы:
Сделай это:
В файле манифеста Android объявите следующее.
Затем напишите класс:
Теперь везде звоните,
MyApplication.getAppContext()
чтобы получить статически контекст вашего приложения.источник
static context
переменную какvolatile
?Большинство приложений, которым нужен удобный метод для получения контекста приложения, создают свой собственный класс, который расширяется
android.app.Application
.РУКОВОДСТВО
Вы можете сделать это, сначала создав класс в своем проекте, как показано ниже:
Затем в вашем AndroidManifest вы должны указать имя вашего класса в теге AndroidManifest.xml:
Затем вы можете получить контекст приложения любым статическим методом, используя следующее:
ПРЕДУПРЕЖДЕНИЕ
Прежде чем добавить что-то подобное в ваш проект, вы должны рассмотреть, что написано в документации:
ОТРАЖЕНИЕ
Существует также другой способ получить контекст приложения, используя отражение. Отражение часто воспринимается в Android свысока, и я лично считаю, что его нельзя использовать в производстве.
Чтобы получить контекст приложения, мы должны вызвать метод для скрытого класса ( ActivityThread ), который был доступен с API 1:
Существует еще один скрытый класс ( AppGlobals ), который обеспечивает способ получения контекста приложения статическим способом. Он получает контекст с использованием,
ActivityThread
так что на самом деле нет разницы между следующим методом и тем, что опубликован выше:Удачного кодирования!
источник
Предполагая, что мы говорим о получении контекста приложения, я реализовал его в соответствии с предложением @Rohit Ghatol, расширяющего приложение. Что случилось потом, так это то, что нет никакой гарантии, что контекст, полученный таким образом, всегда будет ненулевым. В то время, когда вам это нужно, обычно потому, что вы хотите инициализировать помощника или получить ресурс, который вы не можете отложить во времени; обработка нулевого случая не поможет вам. Таким образом, я понял, что в основном борюсь с архитектурой Android, как указано в документации
и объяснил Дайан Хэкборн
Она также предлагает решение этой проблемы:
Итак, я избавился от расширения Application и передал контекст напрямую в getInstance () хелпера singleton, сохранив ссылку на контекст приложения в приватном конструкторе:
вызывающий затем передаст локальный контекст помощнику:
Таким образом, чтобы правильно ответить на этот вопрос: существуют способы статического доступа к контексту приложения, но все они не должны поощряться, и вы должны предпочесть передачу локального контекста в getInstance () синглтона.
Для тех, кто заинтересован, вы можете прочитать более подробную версию в блоге FWD
источник
getInstance(ctx)
. У вас есть кореньinstance
типа GCMyHelper
, у которого есть закрытое полеmContext
типаContext
, которое ссылается на контекст приложения, собранный через передаваемый контекстgetInstance()
.instance
никогда не устанавливается и не очищается, поэтому GC никогда не будет перехватывать appcontext, на который ссылаетсяinstance
. Вы не пропускаете никакие действия, таким образом это - низкая стоимость IMOthis
inApplication.onCreate()
, что сделает принятый ответ лучше.Нет, я не думаю, что есть. К сожалению, вы застряли, звоня
getApplicationContext()
изActivity
или одного из других подклассовContext
. Также этот вопрос несколько связан.источник
Вот недокументированный способ получить приложение (которое является контекстом) из любой точки потока пользовательского интерфейса. Он опирается на скрытый статический метод
ActivityThread.currentApplication()
. Должно работать как минимум на Android 4.x.Обратите внимание, что этот метод может возвращать значение null, например, когда вы вызываете метод вне потока пользовательского интерфейса, или приложение не связано с потоком.
Еще лучше использовать решение @RohitGhatol , если вы можете изменить код приложения.
источник
Это зависит от того, для чего вы используете контекст. Я могу вспомнить хотя бы один недостаток этого метода:
Если вы пытаетесь создать
AlertDialog
сAlertDialog.Builder
,Application
контекст не будет работать. Я считаю, что вам нужен контекст для текущегоActivity
...источник
Котлин путь :
Manifest:
MyApplication.kt
Вы можете получить доступ к собственности через
MyApplication.instance
источник
Если вы открыты для использования RoboGuice , вы можете вставить контекст в любой класс, какой захотите. Вот небольшой пример того, как сделать это с RoboGuice 2.0 (бета 4 на момент написания этой статьи)
источник
Я использовал это в какой-то момент:
Это правильный контекст, который я использовал при получении системных сервисов и работал.
Но я использовал его только в модификациях фреймворка / базы и не пробовал в приложениях для Android.
Предупреждение , что вы должны знать: При регистрации для радиовещательных приемников с этим контекстом, он не будет работать , и вы получите:
источник
Котлин
и получить контекст как
или
источник
Вы можете использовать следующее:
MainActivity.java:
Любой другой класс:
источник
Если вы не хотите изменять файл манифеста, вы можете вручную сохранить контекст в статической переменной в вашей начальной активности:
И просто установите контекст, когда ваша деятельность (или действия) начинаются:
Примечание: как и все другие ответы, это потенциальная утечка памяти.
источник
Я думаю, что вам нужно тело для
getAppContext()
метода:источник
Согласно этому источнику вы можете получить свой собственный контекст, расширив ContextWrapper
JavaDoc для ContextWrapper
источник
Если по какой-то причине вам нужен контекст приложения в любом классе, а не только в тех, которые расширяют приложение / активность, возможно, для некоторых фабричных или вспомогательных классов. Вы можете добавить следующий синглтон в ваше приложение.
затем инициализируйте его в onCreate вашего класса приложения с
использовать его в любом месте, позвонив
Однако я не рекомендую этот подход ни к чему, кроме контекста приложения. Как это может вызвать утечки памяти.
источник
Я использую вариацию шаблона проектирования Singleton, чтобы помочь мне в этом.
Я затем вызвать
ApplicationContextSingleton.setContext( this );
в моей activity.onCreate () иApplicationContextSingleton.setContext( null );
в OnDestroy () ;источник
Я только что выпустил JQuery-фреймворк для Android под названием Vapor API, который призван упростить разработку приложений.
Класс центрального
$
фасада поддерживаетWeakReference
(ссылка на потрясающую статью в блоге Java об этом Итана Николаса) в текущийActivity
контекст, который вы можете получить, вызвав:A
WeakReference
поддерживает ссылку, не предотвращая сборку мусора, возвращая исходный объект, поэтому у вас не должно быть проблем с утечками памяти.Недостатком, конечно, является то, что вы рискуете, что
$.act()
может вернуть ноль. Я еще не сталкивался с этим сценарием, так что, возможно, это просто минимальный риск, о котором стоит упомянутьВы также можете установить контекст вручную, если вы не используете его в
VaporActivity
качествеActivity
класса:Кроме того, большая часть инфраструктуры Vapor API использует этот хранимый контекст по своей сути, что может означать, что вам вообще не нужно хранить его самостоятельно, если вы решите использовать среду. Проверьте сайт для получения дополнительной информации и образцов.
Надеюсь, это поможет :)
источник
Ответ Рохита кажется правильным. Тем не менее, имейте в виду, что «Instant Run» в AndroidStudio зависит от отсутствия
static Context
атрибутов в вашем коде, насколько я знаю.источник
в Kotlin, помещая Context / App Context в объект-компаньон, все еще выдают предупреждение
Do not place Android context classes in static fields; this is a memory leak (and also breaks Instant Run)
или если вы используете что-то вроде этого:
Это просто дурак, чтобы не обнаружить утечку памяти, экземпляр App все еще может вызвать утечку памяти, так как класс Application и его потомок являются Context.
Кроме того, вы можете использовать функциональный интерфейс или функциональные свойства, чтобы помочь вам получить контекст вашего приложения.
Просто создайте объектный класс:
или вы можете использовать его более безопасно, используя обнуляемый тип:
и в своем классе приложения добавьте эту строку:
и в своем манифесте объявите имя приложения
. MyApp
Когда вы хотите получить контекст просто позвоните:
Надеюсь, это поможет.
источник
Попробуйте что-то вроде этого
источник