В приложении Android есть что-то не так со следующим подходом:
public class MyApp extends android.app.Application {
private static MyApp instance;
public MyApp() {
instance = this;
}
public static Context getContext() {
return instance;
}
}
и передать его везде (например, SQLiteOpenHelper), где требуется контекст (и, конечно, не утечка)?
android
android-context
Янченко
источник
источник
<application>
узел файла AndroidManifest.xml включить следующее определение атрибута:android:name="MyApp"
. MyApp должен находиться в том же пакете, на который ссылается ваш манифест.Ответы:
У этого подхода есть пара потенциальных проблем, хотя во многих случаях (например, в вашем примере) он будет работать хорошо.
В частности, вы должны быть осторожны, когда имеете дело со всем, что связано с тем,
GUI
что требуетContext
. Например, если вы передадите Контекст приложения в,LayoutInflater
вы получите Исключение. Вообще говоря, ваш подход отлично: это хорошая практика , чтобы использоватьActivity's
Context
в том , чтоActivity
иApplication Context
при передаче контекста за пределами сферы действия ,Activity
чтобы избежать утечек памяти .Кроме того , в качестве альтернативы к вашему шаблону вы можете использовать ярлык вызова
getApplicationContext()
наContext
объект (например, активность) , чтобы получить контекст приложений.источник
LayoutInflator
только что сработало для меня. Должны быть изменены за последние три года.По моему опыту такой подход не должен быть необходимым. Если вам нужен контекст для чего-либо, вы обычно можете получить его через вызов View.getContext () и, используя
Context
полученный там, вы можете вызвать Context.getApplicationContext (), чтобы получитьApplication
контекст. Если вы пытаетесь получитьApplication
контекст из этого,Activity
вы всегда можете вызвать Activity.getApplication (), которая должна быть в состоянии быть передана какContext
необходимо для вызоваSQLiteOpenHelper()
.В целом, похоже, нет проблем с вашим подходом к этой ситуации, но при работе
Context
просто убедитесь, что вы не теряете память нигде, как описано в официальном блоге разработчиков Google Android .источник
Некоторые люди спрашивают: как синглтон может вернуть нулевой указатель? Я отвечаю на этот вопрос. (Я не могу ответить в комментарии, потому что мне нужно отправить код.)
Он может возвращать ноль между двумя событиями: (1) класс загружен и (2) объект этого класса создан. Вот пример:
Давайте запустим код:
Вторая строка показывает, что Y.xinstance и X.yinstance равны нулю ; они являются нулевыми, потому что переменные X.xinstance и Y.yinstance были прочитаны, когда они были нулевыми.
Это можно исправить? Да,
и этот код не показывает аномалию:
НО это не вариант для
Application
объекта Android : программист не контролирует время, когда он создается.Еще раз: разница между первым примером и вторым состоит в том, что второй пример создает экземпляр, если статический указатель равен нулю. Но программист не может создать на объект Android приложения , прежде чем система решает сделать это.
ОБНОВИТЬ
Еще один загадочный пример, где бывают инициализированные статические поля
null
.Main.java :
И вы получите:
Обратите внимание, что вы не можете переместить объявление статической переменной на одну строку выше, код не будет компилироваться.
источник
Класс применения:
Объявите приложение в AndroidManifest:
Применение:
источник
Вы пытаетесь создать оболочку для получения контекста приложения, и существует вероятность, что он может вернуть
null
указатель « ».Насколько я понимаю, я думаю, что лучше подходить к любому из 2
Context.getApplicationContext()
илиActivity.getApplication()
.источник
Это хороший подход. Я тоже этим пользуюсь. Я бы только предложил переопределить,
onCreate
чтобы установить синглтон вместо использования конструктора.И так как вы упомянули
SQLiteOpenHelper
:onCreate ()
вы можете открыть базу данных.Лично я думаю, что в документации неправильно сказано, что обычно нет необходимости создавать подкласс Application . Я думаю, что все наоборот: вы всегда должны подкласс Application.
источник
Я бы использовал Application Context, чтобы получить системную службу в конструкторе. Это облегчает тестирование и приносит пользу от состава
Тогда тестовый класс будет использовать перегруженный конструктор.
Android будет использовать конструктор по умолчанию.
источник
Мне это нравится, но я бы предложил синглтон:
источник
new
Приложение самостоятельно (с возможным исключением модульного тестирования). Операционная система сделает это. Вы также не должны иметь конструктор. Вот для чегоonCreate
.Я использую тот же подход, я предлагаю написать синглтон немного лучше:
но я не использую везде, я использую
getContext()
иgetApplicationContext()
где я могу это сделать!источник